:fire: :fire: :fire:
We are using [email protected].
We're working on a React Native App at my company. We're trying to use 2 separate Firbase Projects within our app. One is used for push notifications, and the other is used for Firestore.
On iOS, the push notification project is initialized using GoogleService-Info.plist. The Firestore project is initialized using JavaScript calls in React Native Firebase. Both projects make React Native Firebase calls to do auth anonymously.
When we save files while running the iOS app, we get native exceptions in React Native Firebase when the React Native hot reloading tries to reload the app.
It seems related to the native code that handles authorization.
Click To Expand
#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
target 'cca-platform-v5' do
pod 'ExpoKit',
:git => "http://github.com/expo/expo.git",
:tag => "ios/2.11.0",
:subspecs => [
"Core"
],
:inhibit_warnings => true
# Install unimodules
require_relative '../node_modules/react-native-unimodules/cocoapods.rb'
use_unimodules!(exclude: ['expo-face-detector'])
pod 'React',
:path => "../node_modules/react-native",
:inhibit_warnings => true,
:subspecs => [
"Core",
"ART",
"RCTActionSheet",
"RCTAnimation",
"RCTCameraRoll",
"RCTGeolocation",
"RCTImage",
"RCTNetwork",
"RCTText",
"RCTVibration",
"RCTWebSocket",
"DevSupport",
"CxxBridge"
]
pod 'yoga',
:path => "../node_modules/react-native/ReactCommon/yoga",
:inhibit_warnings => true
pod 'DoubleConversion',
:podspec => "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec",
:inhibit_warnings => true
pod 'Folly',
:podspec => "../node_modules/react-native/third-party-podspecs/Folly.podspec",
:inhibit_warnings => true
pod 'glog',
:podspec => "../node_modules/react-native/third-party-podspecs/glog.podspec",
:inhibit_warnings => true
pod 'react-native-add-calendar-event', :path => '../node_modules/react-native-add-calendar-event'
pod 'RNDeviceInfo', :path => '../node_modules/react-native-device-info'
pod 'react-native-music-control', :path => '../node_modules/react-native-music-control'
pod 'RNFirebase', :path => '../node_modules/react-native-firebase/ios'
pod 'Firebase/Core', '~> 6.2.0'
pod 'Firebase/Firestore', '~> 6.2.0'
pod 'Firebase/Auth', '~> 6.2.0'
pod 'Firebase/Messaging', '~> 6.2.0'
pod 'react-native-add-calendar-event', :path => '../node_modules/react-native-add-calendar-event'
pod 'react-native-video', :path => '../node_modules/react-native-video'
pod 'react-native-splash-screen', :path => '../node_modules/react-native-splash-screen'
pod 'SentryReactNative', :path => '../node_modules/react-native-sentry'
post_install do |installer|
installer.pods_project.main_group.tab_width = '2';
installer.pods_project.main_group.indent_width = '2';
installer.target_installation_results.pod_target_installation_results
.each do |pod_name, target_installation_result|
if pod_name == 'ExpoKit'
target_installation_result.native_target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)']
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'EX_DETACHED=1'
# Enable Google Maps support
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'HAVE_GOOGLE_MAPS=1'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'HAVE_GOOGLE_MAPS_UTILS=1'
end
end
if ['Amplitude-iOS','Analytics','AppAuth','Branch','CocoaLumberjack','FBSDKCoreKit','FBSDKLoginKit','FBSDKShareKit','GPUImage','JKBigInteger2'].include? pod_name
target_installation_result.native_target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '10.0'
end
end
# Can't specify this in the React podspec because we need to use those podspecs for detached
# projects which don't reference ExponentCPP.
if pod_name.start_with?('React')
target_installation_result.native_target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '10.0'
config.build_settings['HEADER_SEARCH_PATHS'] ||= ['$(inherited)']
end
end
# Build React Native with RCT_DEV enabled and RCT_ENABLE_INSPECTOR and
# RCT_ENABLE_PACKAGER_CONNECTION disabled
next unless pod_name == 'React'
target_installation_result.native_target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)']
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'RCT_DEV=1'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'RCT_ENABLE_INSPECTOR=0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'ENABLE_PACKAGER_CONNECTION=0'
end
end
end
end
#### `AppDelegate.m`:
// Copyright 2015-present 650 Industries. All rights reserved.
#import "AppDelegate.h"
#import <Firebase.h>
#import "RNFirebaseNotifications.h"
#import "RNFirebaseMessaging.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
[RNFirebaseNotifications configure];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[super applicationWillEnterForeground:application];
}
#pragma mark - Background Fetch
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[super application:application performFetchWithCompletionHandler:completionHandler];
}
#pragma mark - Handling URLs
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [super application:app openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
}
#pragma mark - Notifications
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)token
{
[super application:application didRegisterForRemoteNotificationsWithDeviceToken:token];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
{
[super application:application didFailToRegisterForRemoteNotificationsWithError:err];
}
// firebase
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}
@end
## React Native Firebase Javascript code
### firebase.js (initializes from GoogleService-Info.plist
// @flow
import firebase from 'react-native-firebase';
const apiDebug = require('debug')('ccaapp:firebase:api');
const initializeFirebase = () => {
apiDebug('initializeFirebase() ');
// sign in anonymously to gain access to firestore
const firebaseSignInPromise = firebase
.auth()
.signInAnonymously()
.then(data => {
apiDebug('firebase authed anonymously, uid: ', data.user.uid);
})
.catch(ex => {
apiDebug('error initing firebase: ', ex);
});
// enable offline persistence
const firebaseSettingsPromise = firebase
.firestore()
.settings({ isPersistenceEnabled: true })
.then(() => apiDebug('set firebase to offline persistence mode'));
return Promise.all([firebaseSignInPromise, firebaseSettingsPromise]);
};
const FirebaseAPI = {
initializeFirebase,
};
export default FirebaseAPI;
### mobiledb.js (initialized from code)
import firebase from 'react-native-firebase';
import { firebaseConfig } from '../config/mobiledb';
const apiDebug = require('debug')('ccaapp:mobiledb:api');
function initializeMobileDBApp() {
apiDebug('initializeMobileDBApp start');
apiDebug('initializeMobileDBApp firebase.apps ', JSON.stringify(firebase.apps, null, 2));
let mobileDBApp;
if (firebase.apps && firebase.apps.length === 2) {
apiDebug('initializeMobileDBApp mobileDBApp is initialized');
mobileDBApp = firebase.app('cca-mobiledb');
} else {
apiDebug('initializeMobileDBApp mobileDBApp was not initialized');
mobileDBApp = firebase.initializeApp(firebaseConfig, 'cca-mobiledb');
}
return mobileDBApp.onReady().then(() => {
apiDebug('initializeMobileDBApp mobileDBApp.onReady().then()');
apiDebug('initializeMobileDBApp firebase.apps ', JSON.stringify(firebase.apps, null, 2));
return firebase
.app('cca-mobiledb')
.auth()
.signInAnonymously()
.then(data => {
apiDebug('configureMobileDB() firebase authed anonymously');
return firebase.app('cca-mobiledb');
})
.catch(error => {
apiDebug('configureMobileDB() error initing firebase: ', JSON.stringify(error, null, 2));
});
});
}
async function getMobileDBFirestore() {
return Promise.resolve(firebase.app('cca-mobiledb').firestore());
}
const MobileDBAPI = {
initializeMobileDBApp,
getMobileDBFirestore,
};
export default MobileDBAPI;
Click To Expand
**`react-native info` output:**
React Native Environment Info:
System:
OS: macOS 10.14.5
CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
Memory: 1.30 GB / 32.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 10.15.3 - ~/.nvm/versions/node/v10.15.3/bin/node
npm: 6.4.1 - ~/.nvm/versions/node/v10.15.3/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
Android SDK:
API Levels: 22, 23, 24, 25, 26, 27, 28, 29
Build Tools: 27.0.3, 28.0.2, 28.0.3
System Images: android-22 | Google APIs Intel x86 Atom_64, android-23 | Google APIs Intel x86 Atom, android-24 | Google APIs Intel x86 Atom, android-Q | Google APIs Intel x86 Atom
IDEs:
Android Studio: 3.4 AI-183.6156.11.34.5522156
Xcode: 10.2.1/10E1001 - /usr/bin/xcodebuild
npmPackages:
react: 16.8.3 => 16.8.3
react-native: https://github.com/expo/react-native/archive/sdk-33.0.0.tar.gz => 0.59.8
npmGlobalPackages:
react-native-cli: 2.0.1
react-native-video: 4.4.1
react-native: 0.59.9
- **Platform that you're experiencing the issue on**:
- [X] 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:**
- `5.5.4`
- **`Firebase` module(s) you're using that has the issue:**
- `Seems to be an issue in React Native Firebase Auth, I see the error in com.facebook.react.RNFirebaseAuthQueue`
- **Are you using `TypeScript`?**
- `Nope`
Think react-native-firebase
is great? Please consider supporting all of the project maintainers and contributors by donating via our Open Collective where all contributors can submit expenses. [Learn More]
React Native Firebase
and Invertase
on Twitter for updates on the library.@paulrenenichols - is there anymore on the stack trace, the screenshot only shows the 1 thread, I imagine there was more and also an error message?
@Salakar Does this help?
@Salakar Here's a clearer view of those logs
@annie-elequin thank you - that's a much clearer view of the actual issue. 馃帀
I can confirm this issue was fixed in the v5.5.5 release - [changelog]
Could you update if possible and report back if you have any further issues. Thanks
Thanks @Salakar for your help on this!
That issue referenced in the PR is definitely our problem - I was optimistic updating would fix it. Unfortunately we're still seeing this even with version 5.5.6 installed.
I updated the package and then totally removed node_modules, updated pods and whatnot, cleaned gradle, cleared the cache.
Here's the logs from the latest run:
Again, this is specifically when there are two initialized firebase apps - commenting out the initialization for one of them actually solves the problem.
Other random info:
Let me know if there's any more information you need from me.
only commenting to say that without running a full 'clean-project-auto' from react-native-clean-project, I wouldn't be 100% sure the rebuild actually rebuilt. I've had bad luck on iOS rebuilding with certainty if I didn't also clear out DerivedData (which is one of the things clean-project-auto does - it also clear out pods and other caches so it's pretty network-expensive, if that is prohibitive you can run 'clean-project' and pick and choose what to do
Hmm we just use a custom "reset" script, I've never seen that library - I'll try using that @mikehardy and follow up with the results!
@annie-elequin and if your reset script has anything it's missing - the author there integrates PRs quickly. That library has saved my bacon countless times as a quick rec for others while troubleshooting things.
Alright, update from my end.
Turns out TOTALLY totally cleaning the project did the trick (thanks for that recommendation @mikehardy !)
However, here's a fun one:
So, I guess I should have mentioned this - we're using Expo SDK v33, mostly bare workflow (we still have expokit for OTA updates).
Upon googling I found this:
https://github.com/expo/expo/issues/5242
(which also links to the react-native-firebase issue that I've looked at)
We were about to update to Expo SDK v34, and since the only workaround is to downgrade to 5.5.4 for now, it looks like we'll go that route until we move on from ExpoKit.
@annie-elequin well that's a shame! glad the project clean worked at least, but what I don't understand from the admob dependency snarl of expo/expo#5242 and #2363 here is why people can't just update the AdMob dependency when they are using ExpoKit 33? Is there something preventing the adoption of the newer AdMob pods on the ExpoKit side?
The change in react-native-firebase was https://github.com/invertase/react-native-firebase/pull/2333/files
The API we are calling is: https://developers.google.com/admob/ios/api/reference/Classes/GADRewardBasedVideoAd#/c:objc(cs)GADRewardBasedVideoAd(py)customRewardString
I looked and can't find any sort of release notes for 'customRewardString' in the AdMob release notes page, and the API isn't versioned, is this some very new API that we're using and there is some reason ExpoKit can't work with it?
@mikehardy
I was actually just about to test upgrading the AdMob pods on the ExpoKit side but I've been away.
Let me get to that and see if there's any further issues with regards to that and if so, people should probably just peg to the new AdMob pod in their Podfile.
@mikehardy I see what youre saying - I can't think why this error would be thrown.
I don't know if this would be useful to the both of you, but I just upgraded to Expo SDK v34 and I still have react-native-firebase at 5.5.4 - but I'm seeing this same "AdMob" issue. I'll come back and update if I find anything else out.
did you make sure you were using the most up to date AdMob library? That would be the 6.6.0 Firebase/AdMob pod in the Podfile
hmm these are the only Firebase related items in our Podfile
well that's a head-scratcher. I wonder what would happen if you did specify Firebase/AdMob as a dependency? It should pull in a version of the ads SDK that works? Or it might blow up spectacularly, or have no change... https://github.com/invertase/react-native-firebase/blob/v5.x.x/tests/ios/Podfile.lock#L15
The pods are moving fast btw - they are on 6.6.0 now, and near as I can tell work just fine with react-native-firebase v5.5.x - I'm using all 4 of those in my work project as well, at 6.6.0 right now
I just tested the change and was unable to get it working as the main ExpoKit core explicitly depends on v7.22.0 of the Google-Mobile-Ads-SDK
. Firebase/AdMob
v6.3.0 requires at least v7.44.0 of the Google-Mobile-Ads-SDK
. But I think this shouldn't take a priority at all and we should just peg our version to v5.5.4 of the react-native-firebase
package since ExpoKit is going to be deprecated in the future.
Thanks for trying that! I agree it should not really take priority although I will say there is a firebase iOS crash bug that is tickled by Firebase pods <= 6.30 on iOS 13+, so when iOS13 is released there will be a scramble to move to ExpoKit 34 if you aren't on it already, so you can move up to higher version pods if you are using Firebase/AdMob as well. This isn't something we can control in react-native-firebase but folks with complicated dependency tangles (and expo + react-native-firebase counts as that, I think) need to plan ahead I think
The main thing I appreciate about your update is that the AdMob SDK does not always indicate what changed and they don't version their API, so I wasn't sure when the customRewardString came in.
Now we know at least that was some time after 7.22, so that's something.
I tested on ExpoKit v34 and that's still pegged to v7.22. So people who need iOS 13 support for AdMob will probably have to get the expo team to update the dependency or go full react-native which is what I am intending to do. I am not using the AdMob SDK so it doesn't affect me but perhaps it might affect someone else.
I mentioned it on the linked expo issue with an @ for an Expo person, perhaps they can bump their AdMob SDK dependency, but they will be aware now at least. Thanks again for the research
ExpoKit 35 will have this fix. It was just merged over there (so I suppose if you were brave you could depend on that commit hash - https://github.com/expo/expo/commit/6f64291f6423ec04c87d8af109d47d7fa7e3b452
Most helpful comment
ExpoKit 35 will have this fix. It was just merged over there (so I suppose if you were brave you could depend on that commit hash - https://github.com/expo/expo/commit/6f64291f6423ec04c87d8af109d47d7fa7e3b452