Closed aminosman closed 3 years ago
Very strange - can you try using current stable just to see if that makes a difference? When you say any network requests, you mean you could just try to fetch some random URL like a web request and that would fail? You don't include the full package.json or Podfile so it's impossible to say what other items might be perturbing things. Does it reproduce if you have nothing but react-native-firebase in there (e.g., start with https://github.com/mikehardy/rnfbdemo/blob/master/make-demo.sh, then alter the index.js / App.js to do nothing but reproduce the issue? Then post it if it reproduces?)
I can't say I've seen this in my app personally and it would be a huge deal if it happened in normal circumstances as getToken is vital for any app that does user messaging, and it's common for users to turn off notifications and background refersh, the behavior is certainly surprising
I will attempt to reproduce from a new project. Yes all network requests that I can see stop. Its strange since the first few network requests work right up until the point where we call getToken
. Then everything from there hangs. I have also update package.json and podfile
@mikehardy I’ve had some users complaining that the app won’t load after the splash screen is hidden, it takes approx 25-30 seconds for it to load on iOS. I followed the whole app initialization (it’s a huge process) and it stucked exactly on the first call to firestore (we’re using v12.9).
Sorry for hijacking this issue with that info but it seems to me that this issue and mine might be related, I ll investigate further tomorrow.
On the other hand, on some android users the app won’t load at all, they just get a blank screen. This was never the issue for both Platforms some versions back.
I will be really interested to see a reproduction here, I hope we can see enough info to get to the bottom of it
I also received some user reports that similar to this issue. I'm not sure, but I don't think it's directly related with react-native-firebase because the reports started after where the RNFB was not changed in my app. I'm trying to reproduce this issue, no concrete results so far.
I'm currently using RN v0.65.1 and RNFB v12.9.1.
The only other times we've seen reports of hangs like this - and apologies in advance this is so vague - it was related to people using redux, and some bizarre (to me!) interaction between hooks, redux and firebase and the network. At this point I'm just trying to add any tiny hunch I have, though it may not be relevant. I can imagine this issue is frustrating
Ok on further investigation I noticed we lost a try catch around the call to getToken
which caused an exception to be thrown in a redux saga of ours when we requested push notification permissions. I am assuming when background data on this does not throw an exception like it does when both background data and notifications are disabled. I greatly appreciate your attention and apologize for the confusion.
Glad that at least "rhymed" with something from the past and maybe helped diagnose, but most importantly that you fixed it. There were two others listening in here, perhaps the same thought process / investigation may yield results for everyone :crossed_fingers:
@mikehardy did some digging on my issue and it turns out that the caching was the issue. It always took 25sec to load the app because at some point during initialisation I have this code witch decides if the user has completed the signup process (it's the first call to firestore during init):
export const userFinishedSignup = async (userId: string) => {
if (userId) {
try {
const server = await firestore().collection("profiles").doc(userId).get(); <----- this takes 25secs
// console.log({ serverExists: server.exists });
if (!server.exists) {
return false;
}
const profile = server.data() as Profile;
return Boolean(
profile.published && profile.firstName && profile.lastName && profile.email
);
} catch (e) {
console.log(e);
return false;
}
}
};
And this is my index.js
(check the comments after "<-----")
import "react-native-gesture-handler";
import * as React from "react";
import { CacheManager } from "@georstat/react-native-image-cache";
import { Dirs } from "react-native-file-access";
import messaging from "@react-native-firebase/messaging";
import { AppRegistry, Text, TextInput } from "react-native";
import App from "./src/App";
import { name as appName } from "./app.json";
import ThemeManager from "./src/themes";
import { useEffect } from "react";
import firestore from "@react-native-firebase/firestore";
import { notify } from "./src/utils/utils";
messaging().setBackgroundMessageHandler(() => Promise.resolve());
CacheManager.config = {
baseDir: `${Dirs.CacheDir}/xxxx/images_cache/`,
blurRadius: 15,
sourceAnimationDuration: 800,
thumbnailAnimationDuration: 800
};
// function HeadlessCheck({ isHeadless }) {
// if (isHeadless) {
// // App has been launched in the background by iOS, ignore
// return null;
// }
// return <App />;
// }
// if (__DEV__) {
// const {
// setupDefaultFlipperReporter
// } = require("react-native-performance-flipper-reporter");
// setupDefaultFlipperReporter();
// }
const ThemedApp = () => {
useEffect(() => {
// Create an scoped async function in the hook
async function applyFirestoreSettings() {
await firestore().settings({
ignoreUndefinedProperties: true,
persistence: false <------- After adding this setting, app starts immediately
// cacheSizeBytes: 25 * 1000000 <---------- If I set persistance to true and uncomment this line the app still takes 25secs to launch.
});
}
// Execute the created function directly
applyFirestoreSettings().catch((e) => {
console.log(e);
notify(e, "error", "while applying Firestore settings");
});
}, []);
return (
<ThemeManager>
<App />
</ThemeManager>
);
};
AppRegistry.registerComponent(appName, () => ThemedApp);
I'll try to play around with cacheSizeBytes
a bit to see if it improves things out.
ps. If you think I should create another issue for this please let me know.
*edit: even after setting `cacheSizeBytes: 1 1048576` (1MB) it still takes 25 secs to load**
edit2: i think it's related: https://github.com/firebase/firebase-ios-sdk/issues/8791
edit3: here's the fix and according to file history this exists since 22 Jul, @mikehardy not being a dick here, can you please rush 8.9.0
when it's released? This seems like a major deal in some cases
I generally release SDK updates same day, or next day. you may also override the SDK version in podfile any time to go forward or backwards
Great digging to find the issue and PR though - I'm on my desktop now (not mobile) and followed through the links. Looks like 8.9.0 should be any moment now...
I will say that the firestore Pod is open source and using Podfile post-install tricks you may actually apply this patch yourself - file is here
mike@osxvm:~/work/Invertase/react-native-firebase/tests (master) % find ios | grep leveldb_migrations.cc
ios/Pods/FirebaseFirestore/Firestore/core/src/local/leveldb_migrations.cc
Before you dismiss that, note that I've done a similarly distasteful-but-necessary thing and it's actually integrated in react-native at the moment :fearful: :sweat_smile:
Thanks for the info @mikehardy (I was thinking if a patch-package
exists for pods 😂), I’m the only dev so no need to apply patch via pod, I’ve just added the missing part on the leveldb_migrations.cc
and everything seems fine now.
Great to hear it! And yes it was a major version bump but the changes probably affect almost no one at this point, should be easy to adopt
Issue
To start, we have only verified this bug in iOS.
So this one is an interesting one. As soon as we launched the updated from version 5 to 12 we started seeing a flurry of issue tickets saying their app was not loading. We spent days debugging and discovered the issue stemmed form users with the iOS settings "Notification" and "Background App Refresh" disabled. If either one was enabled network requests work, otherwise they do not.
Now, how this connects to react native firebase. We also noticed that when the device is in this state we happened to get the following error:
And any network requests that happen after this call/error stall and never return (seemingly blocked)
This lead us down a path where removing calls to
messaging().getToken()
resulted in network requests going through again even with both those setts disabled.That said, this issue did not exist on the older version of the library. Users were able to have those setting disabled and everything worked.
Project Files
Javascript
Click To Expand
``` yield firebaseMessaging().getToken() ``` #### `package.json`: ```json { "dependencies": { "@apollo/client": "^3.4.7", "@formatjs/cli": "^1.1.20", "@invertase/react-native-apple-authentication": "^1.1.1", "@notifee/react-native": "^2.0.0", "@ptomasroos/react-native-multi-slider": "^1.0.0", "@react-native-community/art": "https://github.com/Brewskey/art.git", "@react-native-community/async-storage": "^1.12.1", "@react-native-community/audio-toolkit": "^2.0.3", "@react-native-community/blur": "^3.6.0", "@react-native-community/cameraroll": "^1.3.0", "@react-native-community/geolocation": "^2.0.2", "@react-native-community/google-signin": "git+https://github.com/aminosman/google-signin.git", "@react-native-community/netinfo": "^4.4.0", "@react-native-community/segmented-control": "^1.6.1", "@react-native-community/slider": "^2.0.2", "@react-native-firebase/app": "^12.7.2", "@react-native-firebase/auth": "^12.7.2", "@react-native-firebase/database": "^12.7.2", "@react-native-firebase/messaging": "^12.7.2", "@typescript-eslint/eslint-plugin": "^4.19.0", "@typescript-eslint/parser": "^4.19.0", "@yfuks/react-native-action-sheet": "0.0.4", "agora-react-native-rtm": "^1.2.2-alpha.2", "buffer": "^5.1.0", "bugsnag-react-native": "^2.23.2", "circular-json": "^0.5.3", "eslint-config-prettier": "^2.9.0", "graphql": "^14.7.0", "graphql-tag": "^2.10.1", "hoist-non-react-statics": "^3.3.2", "jsc-android": "^241213.1.0", "lodash": "^4.17.11", "lodash.memoize": "^4.1.2", "lottie-ios": "3.1.8", "lottie-react-native": "4.0.2", "moment": "^2.22.1", "prop-types": "^15.6.1", "qs": "^6.5.2", "react": "17.0.1", "react-devtools": "^4.5.0", "react-intl": "^5.8.5", "react-native": "0.64.2", "react-native-adjust": "^4.29.4", "react-native-agora": "^3.4.6", "react-native-android-call-notification": "git+https://github.com/aminosman/react-native-android-call-notification.git", "react-native-android-open-settings": "^1.2.0", "react-native-appsflyer": "5.1.3", "react-native-billing": "^2.10.0", "react-native-callkeep": "^3.1.1", "react-native-camera": "^4.0.3", "react-native-code-push": "^6.2.1", "react-native-config": "1.4.1", "react-native-contacts": "^5.0.4", "react-native-date-picker": "^3.2.3", "react-native-datepicker": "^1.7.2", "react-native-deprecated-custom-components": "^0.1.2", "react-native-device-info": "^7.0.2", "react-native-fast-image": "^8.3.2", "react-native-fbsdk-next": "^3.0.1", "react-native-fs": "^2.14.1", "react-native-geolocation-service": "^3.1.0", "react-native-gesture-handler": "^1.8.1", "react-native-google-analytics": "^1.3.2", "react-native-haptic-feedback": "^1.8.2", "react-native-iap": "5.1.1", "react-native-image-crop-picker": "^0.26.0", "react-native-image-picker": "^2.3.4", "react-native-image-progress": "^1.1.1", "react-native-image-resizer": "^1.0.0", "react-native-image-zoom-viewer": "^3.0.1", "react-native-in-app-review": "^1.0.5", "react-native-incall-manager": "^3.3.0", "react-native-indicators": "^0.17.0", "react-native-intercom": "^17.0.0", "react-native-keyboard-aware-scroll-view": "^0.9.1", "react-native-keychain": "^3.1.1", "react-native-linear-gradient": "^2.5.6", "react-native-localize": "^1.3.3", "react-native-maps": "0.26.1", "react-native-message-compose": "0.0.6", "react-native-modal": "^11.5.6", "react-native-navigation": "6.9.1", "react-native-pager-view": "^5.0.11", "react-native-permissions": "^2.1.5", "react-native-photo-view": "git://github.com/alwx/react-native-photo-view.git#c58fd6b30d627fa23e39520d4fc3325ade8b0a51", "react-native-popup-menu-android": "^1.0.3", "react-native-progress": "^5.0.0", "react-native-reanimated": "^1.9.0", "react-native-recaptcha-v3": "0.0.16", "react-native-render-html": "^4.2.3", "react-native-restart": "0.0.17", "react-native-segmented-control-tab": "^3.2.2", "react-native-shake": "^3.4.0", "react-native-showdown": "^1.0.1", "react-native-snap-carousel": "^3.9.1", "react-native-store-review": "^0.1.5", "react-native-svg": "^9.13.3", "react-native-swipe-list-view": "^2.0.3", "react-native-swipeable": "^0.6.0", "react-native-swipeout": "^2.3.3", "react-native-tab-navigator": "^0.3.4", "react-native-tab-view": "2.14.4", "react-native-uuid": "^1.4.9", "react-native-vector-icons": "^4.6.0", "react-native-video": "^5.0.0", "react-native-voip-push-notification": "^2.1.0", "react-native-webview": "^7.4.2", "react-redux": "^7.1.1", "recompose": "^0.30.0", "redux": "^4.0.0", "redux-devtools-extension": "^2.13.8", "redux-persist": "^6.0.0", "redux-persist-filesystem-storage": "^2.0.0", "redux-saga": "^1.1.1", "reselect": "^3.0.1", "rn-fetch-blob": "^0.11.2", "sendbird": "^3.0.108", "speedometer": "^1.1.0", "warna": "^0.2.4" }, "devDependencies": { "@babel/core": "^7.12.9", "@babel/plugin-proposal-decorators": "^7.4.0", "@babel/polyfill": "^7.0.0", "@babel/preset-typescript": "^7.8.3", "@babel/runtime": "^7.12.5", "@graphql-codegen/cli": "^1.8.3", "@graphql-codegen/introspection": "1.8.3", "@graphql-codegen/typescript": "1.8.3", "@graphql-codegen/typescript-operations": "1.8.3", "@graphql-codegen/typescript-react-apollo": "1.8.3", "@react-native-community/eslint-config": "^2.0.0", "@types/react": "^16.11.0", "@types/react-native": "^0.61.16", "babel-eslint": "^8.2.3", "babel-jest": "^26.6.3", "babel-plugin-module-resolver": "^4.0.0", "babel-register": "^6.26.0", "bugsnag-sourcemaps": "^1.1.0", "eslint": "7.14.0", "eslint-config-airbnb": "^16.1.0", "eslint-config-react-app": "^2.1.0", "eslint-plugin-babel": "^5.1.0", "eslint-plugin-import": "^2.12.0", "eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-react": "^7.9.0", "eslint-plugin-react-native": "^3.2.1", "extract-react-intl-messages": "^2.3.5", "husky": "^0.14.3", "jest": "^26.6.3", "jest-haste-map": "^23.6.0", "lint-staged": "^9.4.2", "metro-react-native-babel-preset": "^0.64.0", "patch-package": "^6.1.0", "prettier": "^2.0.5", "react-native-mock": "^0.3.1", "react-native-typescript-transformer": "^1.2.13", "react-test-renderer": "17.0.1", "react-native-codegen": "0.0.7", "remote-redux-devtools": "^0.5.16", "remotedev-rn-debugger": "^0.8.4", "typescript": "^3.7.5" }, } ``` #### `firebase.json` for react-native-firebase v6: ```json # N/A ```iOS
Click To Expand
#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby platform :ios, '10' require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' project 'Minder.xcodeproj', 'Staging' => :release def shared_pods pod 'FBSDKCoreKit' , '~> 9.0' pod 'FBSDKLoginKit' , '~> 9.0' pod 'FBSDKShareKit' , '~> 9.0' pod 'FBSDKMessengerShareKit' pod 'Intercom', '7.1.0' pod 'RSKImageCropper', '2.0.1' rn_maps_path = '../node_modules/react-native-maps' pod 'react-native-google-maps', :path => rn_maps_path pod 'GoogleMaps', '3.2.0' pod 'Google-Maps-iOS-Utils' pod 'react-native-appsflyer', :path => '../node_modules/react-native-appsflyer' pod 'react-native-config', :path => '../node_modules/react-native-config' pod 'react-native-contacts', :path => '../node_modules/react-native-contacts' pod 'react-native-geolocation', path: '../node_modules/@react-native-community/geolocation' pod 'react-native-date-picker', :path => '../node_modules/react-native-date-picker' pod 'ReactNativeAudioToolkit', :path => '../node_modules/@react-native-community/audio-toolkit' pod 'Permission-Microphone', :path => '../node_modules/react-native-permissions/ios/Microphone.podspec' pod 'MultiSlider', '~> 1.10.3' pod 'CodePush', :path => '../node_modules/react-native-code-push' pod 'react-native-camera', path: '../node_modules/react-native-camera', subspecs: [ 'FaceDetectorMLKit' ] config = use_native_modules! end target 'Minder' do shared_pods pod 'ReactNativeAudioToolkit', :path => '../node_modules/@react-native-community/audio-toolkit' permissions_path = '../node_modules/react-native-permissions/ios' pod 'Permission-Microphone', :path => "#{permissions_path}/Microphone.podspec" pod 'Permission-Camera', :path => "#{permissions_path}/Camera.podspec" pod 'react-native-agora', :path => '../node_modules/react-native-agora' pod 'RNFastImage', :path => '../node_modules/react-native-fast-image' pod 'react-native-date-picker', :path => '../node_modules/react-native-date-picker' config = use_native_modules! use_react_native!( :path => config[:reactNativePath], # to enable hermes on iOS, change `false` to `true` and then install pods :hermes_enabled => false ) # Enables Flipper. # # Note that if you have use_frameworks! enabled, Flipper will not work and # you should disable the next line. use_flipper!({ 'Flipper-Folly' => '2.5.3', 'Flipper' => '0.87.0', 'Flipper-RSocket' => '1.3.1' }) target 'MinderTests' do inherit! :complete # Pods for testing end post_install do |installer| react_native_post_install(installer) installer.pods_project.build_configurations.each do |config| if config.name == 'Staging' config.build_settings['CONFIGURATION_TEMP_DIR'] = '$(PROJECT_TEMP_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)' config.build_settings['CONFIGURATION_BUILD_DIR'] = '$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)' end end installer.pods_project.targets.each do |target| # Because: https://github.com/luggit/react-native-config/issues/365 # if target.name == 'react-native-config' # phase = target.project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase) # phase.shell_script = "cd ../../"\ # " && RNC_ROOT=./node_modules/react-native-config/"\ # " && export SYMROOT=$RNC_ROOT/ios/ReactNativeConfig"\ # " && ruby $RNC_ROOT/ios/ReactNativeConfig/BuildDotenvConfig.ruby" # target.build_phases << phase # target.build_phases.move(phase,0) # end # end if target.name == "React-Core.common-AccessibilityResources" target.remove_from_project end target.build_configurations.each do |config| if config.name == 'Staging' config.build_settings['CONFIGURATION_TEMP_DIR'] = '$(PROJECT_TEMP_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)' config.build_settings['PODS_CONFIGURATION_BUILD_DIR'] = '${PODS_BUILD_DIR}/Release$(EFFECTIVE_PLATFORM_NAME)' if target.name == 'QBImagePickerController-QBImagePicker' config.build_settings['CONFIGURATION_BUILD_DIR'] = '${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController' end if target.name == 'MLKitFaceDetection-GoogleMVFaceDetectorResources' config.build_settings['CONFIGURATION_BUILD_DIR'] = '${PODS_CONFIGURATION_BUILD_DIR}/MLKitFaceDetection' end if target.name == 'React-Core-AccessibilityResources' config.build_settings['CONFIGURATION_BUILD_DIR'] = '${PODS_CONFIGURATION_BUILD_DIR}/React-Core' end end end end end end ``` #### `AppDelegate.m`: ```objc #import "AppDelegate.h" #import
#import
#import
#import
#import
#import
#import
#import
#import
#import
@import GoogleMaps;
#if __has_include() // from Pod
#import
#else
#import "AppsFlyerTracker.h"
#endif
#import
#import
#import "RNVoipPushNotificationManager.h"
#import "RNCallKeep.h"
#ifdef FB_SONARKIT_ENABLED
#import
#import
#import
#import
#import
#import
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
{
[BugsnagReactNative start];
#ifdef FB_SONARKIT_ENABLED
InitializeFlipper(application);
#endif
NSLog([NSString stringWithFormat: @"[FIREBASE] %@ mode.", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FirebaseDir"]]);
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist" inDirectory:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"FirebaseDir"]];
if ([FIRApp defaultApp] == nil) {
FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];
[FIRApp configureWithOptions:options];
}
NSLog(@"IntercomAppId %@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"IntercomAppId"]);
NSLog(@"GoogleAPIKey %@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"GoogleApiKey"]);
// [GMSPlacesClient provideAPIKey:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"GoogleApiKey"]];
[GMSServices provideAPIKey:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"GoogleApiKey"]];
[Intercom setApiKey:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"IntercomApiKey"] forAppId:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"IntercomAppId"]];
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
NSURL *jsCodeLocation;
#ifdef DEBUG
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
jsCodeLocation = [CodePush bundleURL];
#endif
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions];
self.window.backgroundColor = [UIColor blackColor];
[self voipRegistration];
return [[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary *)options
{
[[AppsFlyerTracker sharedTracker] handleOpenUrl:url options:options];
BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
if (!handled) {
return [RCTLinkingManager application:application openURL:url options:options];
}
return handled;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
// Track Installs, updates & sessions(app opens) (You must include this API to enable tracking)
[[AppsFlyerTracker sharedTracker] trackAppLaunch];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
[[AppsFlyerTracker sharedTracker] handleOpenURL:url sourceApplication:sourceApplication withAnnotation:annotation];
if ([[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation])
return YES;
return [RCTLinkingManager application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
[[AppsFlyerTracker sharedTracker] continueUserActivity:userActivity restorationHandler:restorationHandler];
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// Pass device token to auth.
[[FIRAuth auth] setAPNSToken:deviceToken type:FIRAuthAPNSTokenTypeUnknown];
[Intercom setDeviceToken:deviceToken];
[[AppsFlyerTracker sharedTracker] registerUninstall:deviceToken];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
if ([Intercom isIntercomPushNotification:userInfo]) {
[Intercom handleIntercomPushNotification:userInfo];
return;
}
if ([[FIRAuth auth] canHandleNotification:userInfo]) {
completionHandler(UIBackgroundFetchResultNoData);
return;
}
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"%@", error);
}
// --- Handle updated push credentials
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(PKPushType)type {
// Register VoIP push token (a property of PKPushCredentials) with server
[RNVoipPushNotificationManager didUpdatePushCredentials:credentials forType:(NSString *)type];
}
- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type
{
// --- The system calls this method when a previously provided push token is no longer valid for use. No action is necessary on your part to reregister the push type. Instead, use this method to notify your server not to send push notifications using the matching push token.
}
// --- Handle incoming pushes (for ios <= 10)
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type {
NSLog(@"didReceiveIncomingPushWithPayload called");
[RNVoipPushNotificationManager didReceiveIncomingPushWithPayload:payload forType:(NSString *)type];
}
// --- Handle incoming pushes (for ios >= 11)
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {
// --- Retrieve information from your voip push payload
NSString *uuid = payload.dictionaryPayload[@"uuid"];
NSString *callerName = [NSString stringWithFormat:@"%@", payload.dictionaryPayload[@"name"]];
BOOL video = [[payload.dictionaryPayload objectForKey:@"video"] boolValue];
NSString *notificationType = payload.dictionaryPayload[@"type"];
if ([notificationType isEqualToString:@"missed"]) {
[RNCallKeep endCallWithUUID:uuid reason: 6];
} else {
// --- Process the received push
[RNVoipPushNotificationManager didReceiveIncomingPushWithPayload:payload forType:(NSString *)type];
// --- You should make sure to report to callkit BEFORE execute completion()
[RNCallKeep reportNewIncomingCall:uuid handle:uuid handleType:@"generic" hasVideo: video localizedCallerName:callerName fromPushKit: YES payload:payload.dictionaryPayload withCompletionHandler:completion];
}
// --- this is optional, only required if you want to call `completion()` on the js side
[RNVoipPushNotificationManager addCompletionHandler:uuid completionHandler:completion];
completion();
}
// Register for VoIP notifications
- (void) voipRegistration {
dispatch_queue_t mainQueue = dispatch_get_main_queue();
// Create a push registry object
PKPushRegistry * voipRegistry = [[PKPushRegistry alloc] initWithQueue: mainQueue];
// Set the registry's delegate to self
voipRegistry.delegate = self;
// Set the push type to VoIP
voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}
@end
```
Android
Click To Expand
#### Have you converted to AndroidX? - [ ] my application is an AndroidX application? - [ ] I am using `android/gradle.settings` `jetifier=true` for Android compatibility? - [ ] I am using the NPM package `jetifier` for react-native compatibility? #### `android/build.gradle`: ```groovy // N/A ``` #### `android/app/build.gradle`: ```groovy // N/A ``` #### `android/settings.gradle`: ```groovy // N/A ``` #### `MainApplication.java`: ```java // N/A ``` #### `AndroidManifest.xml`: ```xml ```
Environment
Click To Expand
**`react-native info` output:** ``` OUTPUT GOES HERE ``` - **Platform that you're experiencing the issue on**: - [X] iOS - [ ] Android - [X] **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:** - `12.7.2` - **`Firebase` module(s) you're using that has the issue:** - `e.g. Instance ID` - **Are you using `TypeScript`?** - `Y` & `3.7.5`
React Native Firebase
andInvertase
on Twitter for updates on the library.