Skip to content

[🐛] Cannot receive notification with fcm token on the first launch after reinstall (iOS) #4656

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
3 of 10 tasks
SeungsuKim opened this issue Dec 7, 2020 · 10 comments
Closed
3 of 10 tasks
Labels
platform: ios plugin: messaging FCM only - ( messaging() ) - do not use for Notifications resolution: needs-repro This issue could not be reproduced or needs a repro provided. type: bug New bug report Workflow: Waiting for User Response Blocked waiting for user response.

Comments

@SeungsuKim
Copy link

Issue

When the app starts and a user logins, I get a new fcm token with messaging().getToken() and send the token to my server. I've properly registered both foreground and background notification handler thus it works fine on the first install.

However, when I uninstall and re-install the app, messaging().getToken() gives a new token different from the previous one. If I try to send a notification to the device with this new token, the notification is sent find (with node/firebase-admin and HTTP v1 API). However, the device does not receive the notification. After quitting and re-launching the app, messaging().getToken() method gives the same token but the notifications are received fine.

This issue is shown only with iOS devices.


Project Files

Javascript

Click To Expand

package.json:

"dependencies": {
    "@react-native-community/push-notification-ios": "^1.5.0",
    "@react-native-firebase/analytics": "^7.6.1",
    "@react-native-firebase/app": "^8.4.1",
    "@react-native-firebase/messaging": "^7.8.4",
}

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
# Convert all permissions handlers into static libraries
pre_install do |installer|
  installer.pod_targets.each do |pod|
    if pod.name.start_with?('Permission-')
      def pod.build_type;
        # Uncomment one line depending on your CocoaPods version
        Pod::BuildType.static_library # >= 1.9
        # Pod::Target::BuildType.static_library # < 1.9
      end
    end
  end
end

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
require_relative '../node_modules/react-native-unimodules/cocoapods.rb'

platform :ios, '10.0'

# install! 'cocoapods', 
#   :deterministic_uuids => false

target 'drcha' do
  use_unimodules!
  
  config = use_native_modules!

  use_react_native!(:path => config["reactNativePath"])

  permissions_path = '../node_modules/react-native-permissions/ios'
  
  pod 'Permission-Camera', :path => "#{permissions_path}/Camera.podspec"
  pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications.podspec"
  pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary.podspec"
  # pod 'Permission-MediaLibrary', :path => "#{permissions_path}/MediaLibrary.podspec" # this is needed for audio, video

  pod 'GoogleSignIn', '~> 5.0.2'

  # add pods for any other desired Firebase products
  # https://firebase.google.com/docs/ios/setup#available-pods

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable these next few lines.
  use_flipper!
  post_install do |installer|
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
      end
    end
    flipper_post_install(installer)
  end
end

AppDelegate.m:

#import "AppDelegate.h"

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

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

// Firebase for GoogleSignin, Analytics
#import <Firebase.h>
// Microsoft CodePush for OTA updates
#import <CodePush/CodePush.h>
// Kakao Login Implementation
#import <KakaoOpenSDK/KakaoOpenSDK.h>

// React Native Push Notification IOS
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>

// SplashScreen
#import "RNSplashScreen.h"

#ifdef FB_SONARKIT_ENABLED
#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

@interface AppDelegate () <RCTBridgeDelegate>
 
@property (nonatomic, strong) UMModuleRegistryAdapter *moduleRegistryAdapter;
 
@end
 

@implementation AppDelegate

// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
 [RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
 [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
  [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
 [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// IOS 10+ Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler
{
  [RNCPushNotificationIOS didReceiveNotificationResponse:response];
  completionHandler();
}
// IOS 4-10 Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
 [RNCPushNotificationIOS didReceiveLocalNotification:notification];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#ifdef FB_SONARKIT_ENABLED
  InitializeFlipper(application);
#endif
  if ([FIRApp defaultApp] == nil) {
    [FIRApp configure];
  }
  
  [FIRMessaging messaging].autoInitEnabled = YES;
  
  // update Kakako accessToken
  [KOSession sharedSession].automaticPeriodicRefresh = YES;

  self.moduleRegistryAdapter = [[UMModuleRegistryAdapter alloc] initWithModuleRegistryProvider:[[UMModuleRegistryProvider alloc] init]];

  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"drcha"
                                            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];

  [RNSplashScreen show];
  
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self;

  return YES;
}

//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}

- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
    NSArray<id<RCTBridgeModule>> *extraModules = [_moduleRegistryAdapter extraModulesForBridge:bridge];
    // If you'd like to export some custom RCTBridgeModules that are not Expo modules, add them here!
    return extraModules;
}
 
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [CodePush bundleURL];
#endif
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
                                      sourceApplication:(NSString *)sourceApplication
                                              annotation:(id)annotation {
    if ([KOSession isKakaoAccountLoginCallback:url]) {
        return [KOSession handleOpenURL:url];
    }

    return false;
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
                                                options:(NSDictionary<NSString *,id> *)options {
    if ([KOSession isKakaoAccountLoginCallback:url]) {
        return [KOSession handleOpenURL:url];
    }

    return false;
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [KOSession handleDidBecomeActive];
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [KOSession handleDidEnterBackground];
}

@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:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        buildToolsVersion = "29.0.2"
        minSdkVersion = 21
        compileSdkVersion = 29
        targetSdkVersion = 29
        playServicesVersion = "17.0.0"
        androidMapsVersion = "2.0.3"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath('com.android.tools.build:gradle:4.0.0')
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        classpath 'com.google.gms:google-services:4.3.3'
    }
}

allprojects {
    repositories {
        mavenLocal()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }

        google()
        jcenter()
        maven { url 'https://www.jitpack.io' }
        maven { url 'http://devrepo.kakao.com:8088/nexus/content/groups/public/' }
    }
}

android/app/build.gradle:

apply plugin: "com.android.application"
project.ext.envConfigFiles = [
    debug: "/environments/.env.debug",
    releasestaging: "/environments/.env.staging",
    release: "/environments/.env.release",
]
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
apply from: '../../node_modules/react-native-unimodules/gradle.groovy'
apply plugin: 'com.google.gms.google-services' // <- Add this line

import com.android.build.OutputFile

project.ext.react = [
    enableHermes: false,  // clean and rebuild if changing
]

apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"

/**
 * Set this to true to create two separate APKs instead of one:
 *   - An APK that only works on ARM devices
 *   - An APK that only works on x86 devices
 * The advantage is the size of the APK is reduced by about 4MB.
 * Upload all the APKs to the Play Store and people will download
 * the correct one based on the CPU architecture of their device.
 */
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Run Proguard to shrink the Java bytecode in release builds.
 */
def enableProguardInReleaseBuilds = false

/**
 * The preferred build flavor of JavaScriptCore.
 *
 * For example, to use the international variant, you can use:
 * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
 *
 * The international variant includes ICU i18n library and necessary data
 * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
 * give correct results when using with locales other than en-US.  Note that
 * this variant is about 6MiB larger per architecture than default.
 */
def jscFlavor = 'org.webkit:android-jsc:+'

/**
 * Whether to enable the Hermes VM.
 *
 * This should be set on project.ext.react and mirrored here.  If it is not set
 * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
 * and the benefits of using Hermes will therefore be sharply reduced.
 */
def enableHermes = project.ext.react.get("enableHermes", false);

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        applicationId "com.autopedia.drcha"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 23
        versionName "1.1.0"
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
        }
    }
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
        release {
            storeFile file(RELEASE_STORE_FILE)
            storePassword RELEASE_STORE_PASSWORD
            keyAlias RELEASE_KEY_ALIAS
            keyPassword RELEASE_KEY_PASSWORD
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
            // Note: CodePush updates should not be tested in Debug mode as they are overriden by the RN packager. However, because CodePush checks for updates in all modes, we must supply a key.
            resValue "string", "CodePushDeploymentKey", '"4qIaNp2OEscTXjEOo4J7ZdcOnow191G-C6QVv"'
            resValue "bool", "FIREBASE_ANALYTICS_DEACTIVATED", "true"
        }
        releasestaging {
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            resValue "string", "CodePushDeploymentKey", '"4qIaNp2OEscTXjEOo4J7ZdcOnow191G-C6QVv"'
            resValue "bool", "FIREBASE_ANALYTICS_DEACTIVATED", "true"
            // Note: It is a good idea to provide matchingFallbacks for the new buildType you create to prevent build issues
            // Add the following line if not already there
            matchingFallbacks = ['release']
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://reactnative.dev/docs/signed-apk-android.
            signingConfig signingConfigs.release // needs to be commentized if want to use appcenter
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            resValue "string", "CodePushDeploymentKey", '"Eiu1r4Q3bWoi6gi_iIp7oqG50gQXokcn6mftA"'
            resValue "bool", "FIREBASE_ANALYTICS_DEACTIVATED", "false"
        }
    }

    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // https://developer.android.com/studio/build/configure-apk-splits.html
            def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }

        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    //noinspection GradleDynamicVersion
    implementation "com.facebook.react:react-native:+"  // From node_modules

    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"

    implementation 'com.android.installreferrer:installreferrer:1.0'

    addUnimodulesDependencies()

    debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
      exclude group:'com.facebook.fbjni'
    }

    debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.facebook.flipper'
        exclude group:'com.squareup.okhttp3', module:'okhttp'
    }

    debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.facebook.flipper'
    }

    if (enableHermes) {
        def hermesPath = "../../node_modules/hermes-engine/android/";
        debugImplementation files(hermesPath + "hermes-debug.aar")
        releaseImplementation files(hermesPath + "hermes-release.aar")
        releasestagingImplementation files(hermesPath + "hermes-release.aar")
    } else {
        implementation jscFlavor
    }
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

android/settings.gradle:

rootProject.name = 'drcha'
include ':app', ':react-native-code-push'
apply from: '../node_modules/react-native-unimodules/gradle.groovy'; includeUnimodulesProjects()
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')

MainApplication.java:

package com.autopedia.drcha;

// com.myapp should be your package name
import com.autopedia.drcha.generated.BasePackageList;

import android.app.Application;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Arrays;

import org.unimodules.adapters.react.ModuleRegistryAdapter;
import org.unimodules.adapters.react.ReactModuleRegistryProvider;
import org.unimodules.core.interfaces.SingletonModule;

// CodePush module
import com.microsoft.codepush.react.CodePush;

// Adjust module
// import com.adjust.nativemodule.AdjustPackage;

public class MainApplication extends Application implements ReactApplication {

  private final ReactModuleRegistryProvider mModuleRegistryProvider = new ReactModuleRegistryProvider(
      new BasePackageList().getPackageList(), null);

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      @SuppressWarnings("UnnecessaryLocalVariable")
      List<ReactPackage> packages = new PackageList(this).getPackages();
      // Packages that cannot be autolinked yet can be added manually here, for
      // example:
      // packages.add(new MyReactNativePackage());

      // Add unimodules
      List<ReactPackage> unimodules = Arrays.<ReactPackage>asList(new ModuleRegistryAdapter(mModuleRegistryProvider));
      packages.addAll(unimodules);

      // Add Adjust
      // packages.add(new AdjustPackage());

      return packages;
    }

    @Override
    protected String getJSMainModuleName() {
      return "index";
    }

    @Override
    protected String getJSBundleFile() {
      return CodePush.getJSBundleFile();
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
  }

  /**
   * Loads Flipper in React Native templates. Call this in the onCreate method
   * with something like initializeFlipper(this,
   * getReactNativeHost().getReactInstanceManager());
   *
   * @param context
   * @param reactInstanceManager
   */
  private static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
    if (BuildConfig.DEBUG) {
      try {
        /*
         * We use reflection here to pick up the class that initializes Flipper, since
         * Flipper library is not available in release mode
         */
        Class<?> aClass = Class.forName("com.autopedia.drcha.ReactNativeFlipper");
        aClass.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class).invoke(null, context,
            reactInstanceManager);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (NoSuchMethodException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
    }
  }
}

AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.autopedia.drcha">

  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <permission android:name="com.autopedia.drcha.permission.C2D_MESSAGE" android:protectionLevel="signature" />
  <uses-permission android:name="com.autopedia.drcha.permission.C2D_MESSAGE" />
  <uses-permission android:name="android.permission.VIBRATE" />
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

  <application android:name=".MainApplication" android:label="@string/app_name" android:requestLegacyExternalStorage="true" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true">
    <!-- Add this SplashActivity -->
    <activity android:name=".SplashActivity" android:theme="@style/SplashTheme" android:label="@string/app_name">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:exported="true" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.INFO" />
      </intent-filter>
    </activity>
    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    <meta-data android:name="com.google.android.geo.API_KEY" android:value="AIzaSyBc8wj4X5C6GPTGfe_XvSjUUD-VX8Lkjn0"/>
    <meta-data android:name="firebase_analytics_collection_deactivated" android:value="@bool/FIREBASE_ANALYTICS_DEACTIVATED"/>

    <!-- You will also only need to add this uses-library tag -->
    <uses-library android:name="org.apache.http.legacy" android:required="false"/>

    <!-- React Native Push Notification Configuration -->
    <meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name" android:value="채팅 알림"/>
    <meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description" android:value="상담사로부터의 채팅 알림"/>

    <!-- Change the value to true to enable pop-up for in foreground (remote-only, for local use ignoreInForeground) -->
    <meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground" android:value="false"/>
    <!-- Change the value to false if you don't want the creation of the default channel -->
    <meta-data android:name="com.dieam.reactnativepushnotification.channel_create_default" android:value="false"/>
    <!-- Change the resource name to your App's accent color - or any other color you want -->
    <meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="@color/app_bg"/>
    <!-- or @android:color/{name} to use a standard color -->

    <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
    <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
    <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
      <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
      </intent-filter>
    </receiver>

    <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="false">
      <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
      </intent-filter>
    </service>
  </application>

</manifest>


Environment

Click To Expand

react-native info output:

System:
    OS: macOS 10.15.6
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 63.60 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 14.13.1 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.8 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.9.3 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.2, DriverKit 20.0, macOS 11.0, tvOS 14.2, watchOS 7.1
    Android SDK: Not Found
  IDEs:
    Android Studio: 4.0 AI-193.6911.18.40.6626763
    Xcode: 12.2/12B45b - /usr/bin/xcodebuild
  Languages:
    Java: 13.0.2 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: ^4.12.0 => 4.13.0 
    react: 16.13.1 => 16.13.1 
    react-native: 0.63.2 => 0.63.2 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found
  • 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:
    • ^7.8.4
  • Firebase module(s) you're using that has the issue:
    • messaging
  • Are you using TypeScript?
    • Y / ^4.0.3


@SeungsuKim SeungsuKim added help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report labels Dec 7, 2020
@mikehardy
Copy link
Collaborator

I knew just from the title that when I expanded your versions section I would find old versions.
You've been bitten by this: #4299
You must use underlying firebase-ios-sdk v7.0.0 or higher
For that you must use current versions of react-native-firebase
I recommend you update to current, which is v10.1.0
Yes that seems like a big version jump but do not fear: it was mostly due to an internal version change where now all the packages have the same number at the same time (much less confusing!) so I had to adopt the next major version after the current largest number from all the packages and one was already on v9.x, so everything got v10. There are a couple breaking changes but they are tiny tiny, and noted in the all-in-one release notes.

@SeungsuKim
Copy link
Author

SeungsuKim commented Dec 7, 2020

@mikehardy

I've updated both @react-native-firebase/app and @react-native-firebasse/messaging. Now my packages' versions are

"@react-native-firebase/app": "^10.1.0",
"@react-native-firebase/messaging": "^10.1.1",

However, the issue is behaving differently, not resolved.

The notification works fine on the first app launch. After uninstall and re-installing the app, the given token is different from the first token. However, this token gives not-registered error, which is different from the original error: sending notification successes but cannot be received from the iOS devices. After hard-quitting and relaunching the app, a notification is received with the same token.

The response of HTTP API with not-registered error is as follows:

{
    "multicast_id": 7116770526969181322,
    "success": 0,
    "failure": 1,
    "canonical_ids": 0,
    "results": [
        {
            "error": "NotRegistered"
        }
    ]
}

Every native configs, such as AppDelegate.m and XCode's Signing-Capabilities, are done the same as the document. I can't understand why notifications are sometimes received or not with the same FCM token.

  • Something strange and different from before the update, is that HTTP API is keeping returning not-registered error after relaunching the app. At the same time, notification sent by the node's firebase-admin is received well.

@mikehardy
Copy link
Collaborator

So after the update the admin sdk works for the token you get? What I am trying to understand is: after the update, you do get a valid token that works in some contexts, and notifications are received from those contexts on first launch? If that's correct then I'm not sure how I explain same token working from one senders and not the other

@SeungsuKim
Copy link
Author

SeungsuKim commented Dec 7, 2020

@mikehardy

I've experimented with various conditions, and this is what I've found until now:

  • Every time when the app is installed, the FCM token is updated to a new value (which is trivial)
  • However, sometimes the new token gives not-registered error when tries to send a message with both HTTP API and node's firebase-admin package.
  • If not-registered error once happens, re-launching the app does not give a new token and the not-registered error keep happens.
  • I'm currently using the react-native-push-notification package to show local notification on foreground state and handle notification press. I'm calling PushNotification.configure() method on top component's useEffect. If I remove the call, everything works fine.
  • Since I'm using react-native-push-notification only for local notification, I've only implemented some functions in AppDelegate.m among the functions that react-native-push-notification recommends to implement. The unchecked functions are the functions that are implemented in AppDelegate.m.
    • applicationDidRegisterUserNotificationSettings
    • applicationDidRegisterForRemoteNotificationsWithDeviceToken
    • applicationDidReceiveRemoteNotification
    • applicationDidFailToRegisterForRemoteNotificationsWithError
    • userNotificationCenterDidReceiveNotificationResponse
    • applicationDidReceiveLocalNotification
    • userNotificationCenterWillPresentNotificationWithCompletionHandler

What I'm keep looking for is an optimal solution for handling local notification with @react-native-firebase/messaging. The document recommends Notifee, but it's not free. Is there any best practice example?

@mikehardy
Copy link
Collaborator

The packages you are using are fine, should work. The problem you're having is token generation and registration not reception

Can you provide the firebase-ios-sdk version, for the avoidance of doubt? And perhaps retest with 7.2.0 making sure that it is a clean build?

Finally while we are working on this it may be possible (and maybe I'll implement this in my app!) you can have a firebase function call that attempts to send the current token a data only message, and logs success in firestore then return the status. If it's unregistered, call delete token, store the new one and maybe try again. If it fails again raise an alert or log analytics or something just as a means of detection and self healing

In the meantime if you Google firebase ios quickstart and use the messaging Quick start to reproduce without react native layer that is part of the isolation we need to resolve

@SeungsuKim
Copy link
Author

Podfile.lock

  - Firebase/Analytics (7.1.0):
    - Firebase/Core
  - Firebase/Core (7.1.0):
    - Firebase/CoreOnly
    - FirebaseAnalytics (= 7.1.0)
  - Firebase/CoreOnly (7.1.0):
    - FirebaseCore (= 7.1.0)
  - Firebase/Crashlytics (7.1.0):
    - Firebase/CoreOnly
    - FirebaseCrashlytics (~> 7.1.0)
  - Firebase/Messaging (7.1.0):
    - Firebase/CoreOnly
    - FirebaseMessaging (~> 7.1.0)
  - FirebaseAnalytics (7.1.0):
    - FirebaseCore (~> 7.0)
    - FirebaseInstallations (~> 7.0)
    - GoogleAppMeasurement (= 7.1.0)
    - GoogleUtilities/AppDelegateSwizzler (~> 7.0)
    - GoogleUtilities/MethodSwizzler (~> 7.0)
    - GoogleUtilities/Network (~> 7.0)
    - "GoogleUtilities/NSData+zlib (~> 7.0)"
    - nanopb (~> 2.30906.0)
  - FirebaseCore (7.1.0):
    - FirebaseCoreDiagnostics (~> 7.0)
    - GoogleUtilities/Environment (~> 7.0)
    - GoogleUtilities/Logger (~> 7.0)
  - FirebaseCoreDiagnostics (7.2.0):
    - GoogleDataTransport (~> 8.0)
    - GoogleUtilities/Environment (~> 7.0)
    - GoogleUtilities/Logger (~> 7.0)
    - nanopb (~> 2.30906.0)
  - FirebaseCrashlytics (7.1.0):
    - FirebaseCore (~> 7.0)
    - FirebaseInstallations (~> 7.0)
    - GoogleDataTransport (~> 8.0)
    - nanopb (~> 2.30906.0)
    - PromisesObjC (~> 1.2)
  - FirebaseInstallations (7.2.0):
    - FirebaseCore (~> 7.0)
    - GoogleUtilities/Environment (~> 7.0)
    - GoogleUtilities/UserDefaults (~> 7.0)
    - PromisesObjC (~> 1.2)
  - FirebaseInstanceID (7.2.0):
    - FirebaseCore (~> 7.0)
    - FirebaseInstallations (~> 7.0)
    - GoogleUtilities/Environment (~> 7.0)
    - GoogleUtilities/UserDefaults (~> 7.0)
  - FirebaseMessaging (7.1.0):
    - FirebaseCore (~> 7.0)
    - FirebaseInstanceID (~> 7.0)
    - GoogleUtilities/AppDelegateSwizzler (~> 7.0)
    - GoogleUtilities/Environment (~> 7.0)
    - GoogleUtilities/Reachability (~> 7.0)
    - GoogleUtilities/UserDefaults (~> 7.0)

It seems like I'm using firebase-ios-sdk version 7.1. I'll re-test with 7.2.0!
Thank you for the ideas! I'll try my best to resolve this issue.

@mikehardy
Copy link
Collaborator

I mean to re-open this actually - I do think you might be on to something, the initial token registration I marked this as a dupe for should have been resolved in 7.0.0. I think there may be a problem and while there may be some clever-ish workaround it means there would be a problem. In the end it will likely be in firebase-ios-sdk so if reproduced in 7.2.0 definitely try the pure firebase-ios-sdk quickstart to reproduce as a bug in that repo will be the place to go, but we will obviously be very interested here

@mikehardy mikehardy reopened this Dec 7, 2020
@stale
Copy link

stale bot commented Jan 10, 2021

Hello 👋, to help manage issues we automatically close stale issues.
This issue has been automatically marked as stale because it has not had activity for quite some time. Has this issue been fixed, or does it still require the community's attention?

This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.

@stale stale bot added the Type: Stale Issue has become stale - automatically added by Stale bot label Jan 10, 2021
@mikehardy
Copy link
Collaborator

This needs either a clean reproduction here with a self-contained App.js file that shows the issue when dropped in the result of a project created fro https://github.com/mikehardy/rnfbdemo/blob/master/make-demo.sh or a related issue in firebase-ios-sdk repo created from their auth quickstart - not sure how to advance it otherwise

@stale stale bot removed the Type: Stale Issue has become stale - automatically added by Stale bot label Jan 19, 2021
@mikehardy mikehardy added resolution: needs-repro This issue could not be reproduced or needs a repro provided. Workflow: Waiting for User Response Blocked waiting for user response. platform: ios plugin: messaging FCM only - ( messaging() ) - do not use for Notifications and removed help: needs-triage Issue needs additional investigation/triaging. labels Jan 19, 2021
@jimji1005
Copy link

jimji1005 commented Mar 5, 2021

I might be experiencing the exact same issue here @mikehardy
first install of app sends correctly, delete the app, install again (new token) fcm send returns
{"multicast_id":2989573658988972548,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}

I will provide a demo tomorrow, here are the test logs.
tl;dr

if you switch from install via app store or install via xcode the result changes. install via xcode has a 100% success rate it seems.

prod install app store
f0ebY5tNVEcEmsxkAZUY7_:APA91bHrLcOubZZVu1pWrOCSyjKdi1uVDS8jS9-IchPonWQrerdC0zeMH7kkOh6NhHliNzvwNFZcl45wfG4UOuu5DQUzDFQsmU8qVD6FzBhuY8EXfiUWAPzwBoQf91I0OUL7iRoD6Grd
{"multicast_id":8704624170040153942,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}% 

reboot

prod install app store
eUN-VqtGPEfdoVhb_Fq51v:APA91bF-ikyom49dBIb2FC3PkqO9pEi49jYztrcp8AfK7IfEMtNTPnAPTYHGb-R1gSXNrRNI3GkcsQDlAuyErKguHQTzdb9zo6-GWoqvyGGHTjmAfsz4DZiVNmluhOFC-8NsTc-H3tXp
{"multicast_id":686778996836044070,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}%

prod build via xcode release build
cHxwe_FMlELWurVEOQLlaH:APA91bHYq9HpQRky2lOuxFrlBz0EqWpkJcQaa77GNqxAxXS5VEkAN0UiodjCWun7pokcsS2WOXd6ny66-xvOw8oJ7zOUFUzE93j6S9akxoovnhaDRB64ORz3CPwhUpjLMXlmA8t_zRW6
{"multicast_id":8829717825891531575,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"1614932803534634"}]}%   

prod build via xcode release build
fgcyl5ANNk1_p_gTFqE_VD:APA91bFlkY7VNpAemsnPteHFxuWOnB4jx-WTURj7bv_FeLfaqHx-uUsx99isXVM5K4CL6uiJqp4F-QXeK_-N3np2lvtWcT0PQeUGOpTfebh5oeelV2UMRuwgfFIoWKBimUlvugu8kwYJ
{"multicast_id":5803065250398928096,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"1614932933498082"}]}%           

prod install via appstore
result not captured!!!

prod install via app store
emKZmWDQO0-NhVR4ONZlF_:APA91bHmQXTMgEaeugRBK4NT6vySem6wIiMcTsS5V4TUvJIPfy4FrURPoBREAW6HFIjz11Fnh1f9v_W8RIJQm2Z8lXublgHhMgNnU_nXQK_b-lP_kiqz2NsKLE4uPt70vQsUl4kIx6Sv
{"multicast_id":5978784653657037303,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}%                   

eGnnPx-5tE1gqu0bI2QiqL:APA91bFbn_bqhILJ4Az58EA0BdYCFmUhymhIoUSztz4Ys2hHiiK11cM0WE-04tQK4Ezb2y2m5VQcrlYnOVIrDZJuu_9vC633lxAXvQRq8kD5bfDchIFRKmvqFae6s9uHBUpmwx0HBiE1
{"multicast_id":7554033889458644795,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform: ios plugin: messaging FCM only - ( messaging() ) - do not use for Notifications resolution: needs-repro This issue could not be reproduced or needs a repro provided. type: bug New bug report Workflow: Waiting for User Response Blocked waiting for user response.
Projects
None yet
Development

No branches or pull requests

3 participants