Skip to content

onSnapshot hanging after killing iOS and restarting #3614

@dsessoms

Description

@dsessoms

Issue

Using onSnapshot works when first installing an iOS app with a release scheme, but once the app is killed and restarted a couple of times (1-2 on average), onSnapshot fails to return data or throw an error.

After extensive testing I found that setting includeMetadataChanges to true prevented this issue, but does lead to more events than desired.

useEffect(() => {
    if (!uid || uid === '') {
      log(`uid: ${uid}`);
      setBoordUser(undefined);
      return;
    }
    log(`uid: ${uid}`);
    const subscriber = firestore()
      .collection('users')
      .doc(uid)
      .onSnapshot(
        (snapshot) => {
          if (!snapshot || !snapshot.exists) {
            setBoordUser(undefined);
          } else {
            setBoordUser(snapshot.data() as IBoordUser);
          }
        },
        (error) => {
          log(JSON.stringify(error));
        },
      );
    return () => subscriber();
  }, [uid]);

Project Files

Javascript

Click To Expand

package.json:

{
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "npx react-native run-android --verbose",
    "android-release": "npx react-native run-android --variant=release",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "code-push": "ts-node ./bin/code-push.ts",
    "bundle-android": "cd android && ./gradlew bundleRelease",
    "start-android-release": "npx react-native run-android --variant=release",
    "test": "jest",
    "compile": "tsc --noEmit",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
    "dev-tools": "react-devtools",
    "postinstall": "npx jetify"
  },
  "dependencies": {
    "@expo/react-native-action-sheet": "^3.6.0",
    "@invertase/react-native-apple-authentication": "^0.2.0",
    "@react-native-community/cameraroll": "^1.5.2",
    "@react-native-community/google-signin": "^4.0.0",
    "@react-native-community/masked-view": "^0.1.7",
    "@react-native-firebase/analytics": "6.7.1",
    "@react-native-firebase/app": "6.7.1",
    "@react-native-firebase/auth": "6.7.1",
    "@react-native-firebase/database": "6.7.1",
    "@react-native-firebase/dynamic-links": "6.7.1",
    "@react-native-firebase/firestore": "6.7.1",
    "@react-native-firebase/messaging": "6.7.1",
    "@react-native-firebase/remote-config": "6.7.1",
    "@react-native-firebase/storage": "6.7.1",
    "@react-navigation/bottom-tabs": "^5.2.7",
    "@react-navigation/native": "^5.1.4",
    "@react-navigation/stack": "^5.2.9",
    "@sentry/react-native": "^1.3.7",
    "@terrylinla/react-native-sketch-canvas": "^0.8.0",
    "@types/inquirer": "^6.5.0",
    "@types/lodash": "^4.14.149",
    "@types/react-native-vector-icons": "^6.4.5",
    "@types/uuid": "^7.0.3",
    "expo-keep-awake": "^8.1.0",
    "expo-linear-gradient": "^8.1.0",
    "gs": "^0.0.2",
    "inquirer": "^7.1.0",
    "lodash": "^4.17.15",
    "react": "16.11.0",
    "react-native": "0.62.0",
    "react-native-agora": "^2.9.1-alpha.3",
    "react-native-animatable": "^1.3.3",
    "react-native-camera": "^3.22.0",
    "react-native-code-push": "^6.2.0",
    "react-native-confetti": "^0.1.0",
    "react-native-draggable": "^3.1.0",
    "react-native-draggable-flatlist": "^2.3.2",
    "react-native-fs": "^2.16.6",
    "react-native-gesture-handler": "^1.6.1",
    "react-native-home-pressed": "^1.1.4",
    "react-native-paper": "^3.6.0",
    "react-native-reanimated": "^1.7.1",
    "react-native-render-html": "^4.2.0",
    "react-native-safe-area-context": "^0.7.3",
    "react-native-screens": "^2.4.0",
    "react-native-sound": "^0.11.0",
    "react-native-unimodules": "^0.9.0",
    "react-native-vector-icons": "^6.6.0",
    "react-native-webview": "^9.1.3",
    "reanimated-bottom-sheet": "^1.0.0-alpha.19",
    "uuid": "^3.4.0"
  },
  "devDependencies": {
    "@babel/core": "^7.6.2",
    "@babel/runtime": "^7.6.2",
    "@react-native-community/eslint-config": "^1.0.0",
    "@types/jest": "^24.0.24",
    "@types/react-native": "^0.62.0",
    "@types/react-test-renderer": "16.9.2",
    "@typescript-eslint/eslint-plugin": "^2.25.0",
    "@typescript-eslint/parser": "^2.25.0",
    "babel-jest": "^24.9.0",
    "eslint": "^6.5.1",
    "jest": "^24.9.0",
    "metro-react-native-babel-preset": "^0.58.0",
    "prettier": "^2.0.2",
    "react-devtools": "^4",
    "react-test-renderer": "16.11.0",
    "ts-node": "^8.8.2",
    "typescript": "^3.7.3"
  },
  "jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ]
  }
}

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
platform :ios, '10.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
require_relative '../node_modules/react-native-unimodules/cocoapods.rb'

def add_flipper_pods!
  version = '~> 0.33.1'
  pod 'FlipperKit', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitLayoutPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/SKIOSNetworkPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitUserDefaultsPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitReactPlugin', version, :configuration => 'Debug'
end

# Post Install processing for Flipper
def flipper_post_install(installer)
  installer.pods_project.targets.each do |target|
    if target.name == 'YogaKit'
      target.build_configurations.each do |config|
        config.build_settings['SWIFT_VERSION'] = '4.1'
      end
    end
  end
end

target 'App' do
  # Pods for App
  pod 'GoogleSignIn', '~> 5.0.2'
  pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
  pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
  pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
  pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/'
  pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
  pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'

  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  pod 'ReactCommon/callinvoker', :path => "../node_modules/react-native/ReactCommon"
  pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
  pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga', :modular_headers => true

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'

  pod 'react-native-agora', :path => '../node_modules/react-native-agora'

  pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'

  pod 'RNFS', :path => '../node_modules/react-native-fs'

  pod 'react-native-cameraroll', :path => '../node_modules/@react-native-community/cameraroll'

  target 'AppTests' do
    inherit! :complete
    # Pods for testing
  end

  use_native_modules!
  use_unimodules!

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable these next few lines.
  add_flipper_pods!
  post_install do |installer|
    flipper_post_install(installer)
  end
end

target 'App-tvOS' do
  # Pods for App-tvOS

  target 'App-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end
end

AppDelegate.m:

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <Firebase.h>

#import <CodePush/CodePush.h>

#import <UMCore/UMModuleRegistry.h>
#import <UMReactNativeAdapter/UMNativeModulesProxy.h>
#import <UMReactNativeAdapter/UMModuleRegistryAdapter.h>

#if DEBUG
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>

static void InitializeFlipper(UIApplication *application) {
  FlipperClient *client = [FlipperClient sharedClient];
  SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
  [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
  [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
  [client addPlugin:[FlipperKitReactPlugin new]];
  [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
  [client start];
}
#endif

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#if DEBUG
  InitializeFlipper(application);
#endif
  if ([FIRApp defaultApp] == nil) {
    [FIRApp configure];
  }

  self.moduleRegistryAdapter = [[UMModuleRegistryAdapter alloc] initWithModuleRegistryProvider:[[UMModuleRegistryProvider alloc] init]];
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"App"
                                            initialProperties:nil];

  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  return YES;
}

- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
  NSArray<id<RCTBridgeModule>> *extraModules = [_moduleRegistryAdapter extraModulesForBridge:bridge];
  // You can inject any extra modules that you would like here, more information at:
  // https://facebook.github.io/react-native/docs/native-modules-ios.html#dependency-injection
  return extraModules;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [CodePush bundleURL];
#endif
}

@end


Environment

Click To Expand

react-native info output:

 System:
    OS: macOS 10.15.4
    CPU: (8) x64 Intel(R) Core(TM) i5-8279U CPU @ 2.40GHz
    Memory: 39.79 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.13.1 - ~/.nvm/versions/node/v12.13.1/bin/node
    Yarn: 1.21.1 - /usr/local/bin/yarn
    npm: 6.12.1 - ~/.nvm/versions/node/v12.13.1/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.4, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 23, 24, 25, 26, 27, 28
      Build Tools: 23.0.1, 25.0.2, 26.0.2, 26.0.3, 27.0.3, 28.0.3
      System Images: android-27 | Intel x86 Atom_64, android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5791312
    Xcode: 11.4.1/11E503a - /usr/bin/xcodebuild
  npmPackages:
    react: 16.11.0 => 16.11.0 
    react-native: 0.62.0 => 0.62.0
  • Platform that you're experiencing the issue on:
    • iOS
    • Android
    • iOS but have not tested behavior on Android
    • Android but have not tested behavior on iOS
    • Both
  • react-native-firebase version you're using that has this issue:
    • e.g. 6.7.1
  • Firebase module(s) you're using that has the issue:
    • Firestore
  • Are you using TypeScript?
    • Y & 3.7.3


Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions