invertase / react-native-firebase

🔥 A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
https://rnfirebase.io
Other
11.61k stars 2.19k forks source link

🔥 [🐛] Messaging notifications - App doesn't receive notifications from Firebase Messaging (both test and real notifications) #7517

Closed Jobjeuh closed 8 months ago

Jobjeuh commented 8 months ago

Issue

For both Android and iOS my app doesn't receive any notifications.

The app I'm working on retrieves the InstanceID from a user's device via messaging().getToken(). It then uploads that to the server and saves it to the logged in user. However, sending a test Firebase Notification message to an app's instance ID doesn't work. The app doesn't receive a test push notification.

I've read and re-read the docs and how to implement everything about 10 times now, so I'm fairly sure I've set everything up correctly. The app has 1) Firebase messaging installed 2) The correct permissions checked and set 3) (for iOS) Set up everything to enable communication with APNs, both in xcode (capabilities, background modes, certificates, keys and profiles) aswel as the Cloud Messaging tab in the Firebase console 4) Set up the message handlers (messaging().onNotificationOpenendApp() and messaging().getInitialNotification()) 5) Integrated the correct google-services.json and GoogleService-Info.plist files 6) Saved the correct SHA keys in Firebase console for Android 7) And probably a couple more steps that are in the docs

However, even when I try to send a test notification message in the Firebase console, my app doesn't receive anything. This is the case for both iOS and Android, aswel as physical and emulator device.


Project Files

Javascript

Click To Expand

#### `package.json`: ```json { "name": "natuurbeleving", "version": "2.2.0", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "start": "react-native start", "test": "jest", "eslint": "eslint src/context/* . src/navigation/* . src/screens/* . src/shared/* . src/types/*", "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "postinstall": "chmod +x git-hooks/pre-commit" }, "dependencies": { "@miblanchard/react-native-slider": "^2.2.0", "@react-native-assets/slider": "^7.0.5", "@react-native-async-storage/async-storage": "^1.17.11", "@react-native-community/blur": "^4.3.0", "@react-native-community/netinfo": "^9.3.7", "@react-native-firebase/analytics": "^18.7.3", "@react-native-firebase/app": "^18.7.3", "@react-native-firebase/crashlytics": "^18.7.3", "@react-native-firebase/dynamic-links": "^18.7.3", "@react-native-firebase/messaging": "^18.7.3", "@react-navigation/bottom-tabs": "^6.5.2", "@react-navigation/native": "^6.0.16", "@react-navigation/native-stack": "^6.9.4", "@rnmapbox/maps": "^10.1.1", "@scrumble-nl/columbus": "^0.0.2", "@scrumble-nl/eslint-plugin-scrumble-rules": "^1.2.2", "@scrumble-nl/react-custom-hooks": "^2.1.3", "@tanstack/react-query": "^4.19.1", "@turf/nearest-point": "^6.5.0", "@turf/turf": "^6.5.0", "axios": "^1.2.1", "date-fns": "^2.30.0", "html-to-text": "^9.0.5", "react": "18.2.0", "react-hook-form": "^7.43.0", "react-map-gl": "^7.0.20", "react-native": "0.72.4", "react-native-background-fetch": "^4.2.0", "react-native-background-geolocation": "^4.14.5", "react-native-bouncy-checkbox": "^3.0.6", "react-native-gesture-handler": "^2.9.0", "react-native-image-picker": "^5.6.1", "react-native-lightbox-v2": "^0.9.0", "react-native-map-link": "^2.11.2", "react-native-popup-menu": "^0.16.1", "react-native-render-html": "^6.3.4", "react-native-safe-area-context": "^4.4.1", "react-native-screens": "^3.18.2", "react-native-sound": "^0.11.2", "react-native-star-rating-widget": "^1.6.0", "react-native-svg": "^13.14.0", "react-native-text-link": "^1.0.1", "react-native-toast-message": "^2.1.5", "react-native-tracking-transparency": "^0.1.2", "react-native-vector-icons": "^10.0.0", "react-native-video": "^6.0.0-alpha.7" }, "devDependencies": { "@babel/core": "^7.20.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", "@react-native/eslint-config": "^0.72.2", "@react-native/metro-config": "^0.72.11", "@testing-library/react-native": "^12.0.0-rc.0", "@tsconfig/react-native": "^3.0.0", "@types/html-to-text": "^9.0.0", "@types/jest": "^26.0.23", "@types/react": "^18.0.24", "@types/react-native": "^0.66.15", "@types/react-native-vector-icons": "^6.4.12", "@types/react-native-video": "^5.0.14", "@types/react-test-renderer": "^18.0.0", "@typescript-eslint/eslint-plugin": "^5.7.0", "@typescript-eslint/parser": "^5.7.0", "babel-jest": "^29.2.1", "eslint": "^8.19.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-jest": "^27.2.3", "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-native": "^4.0.0", "i": "^0.3.7", "jest": "^29.5.0", "metro-react-native-babel-preset": "^0.76.8", "npm": "^9.8.1", "prettier": "^3.0.2", "react-test-renderer": "18.2.0", "typescript": "^4.9.3" }, "engines": { "node": ">=16" }, "resolutions": { "@types/react": "^17" } } ```

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby $RNFirebaseAsStaticFramework = true # Resolve react_native_pods.rb with node to allow for hoisting require Pod::Executable.execute_command('node', ['-p', 'require.resolve( "react-native/scripts/react_native_pods.rb", {paths: [process.argv[1]]}, )', __dir__]).strip platform :ios, min_ios_version_supported prepare_react_native_project! # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded # # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` # ```js # module.exports = { # dependencies: { # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), # ``` flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled linkage = ENV['USE_FRAMEWORKS'] if linkage != nil Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green use_frameworks! :linkage => linkage.to_sym end $RNMapboxMapsImpl = 'mapbox' target 'Natuurbeleving' do config = use_native_modules! # Flags change depending on the env values. flags = get_default_flags() pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons' pod 'RNFBCrashlytics', :path => '../node_modules/@react-native-firebase/crashlytics' use_frameworks! :linkage => :static use_react_native!( :path => config[:reactNativePath], # Hermes is now enabled by default. Disable by setting this flag to false. :hermes_enabled => flags[:hermes_enabled], :fabric_enabled => flags[:fabric_enabled], # Enables Flipper. # # Note that if you have use_frameworks! enabled, Flipper will not work and # you should disable the next line. # :flipper_configuration => flipper_config, # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/.." ) target 'NatuurbelevingTests' do inherit! :complete # Pods for testing end pre_install do |installer| $RNMapboxMaps.pre_install(installer) end post_install do |installer| $RNMapboxMaps.post_install(installer) installer.pods_project.build_configurations.each do |config| config.build_settings["CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES"] = true end # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 react_native_post_install( installer, config[:reactNativePath], :mac_catalyst_enabled => false ) __apply_Xcode_12_5_M1_post_install_workaround(installer) end end ``` #### `AppDelegate.m`: ```objc #import #import "AppDelegate.h" #import #import @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [FIRApp configure]; // [REQUIRED] Register BackgroundFetch [[TSBackgroundFetch sharedInstance] didFinishLaunching]; self.moduleName = @"IVN Natuur"; // You can add your custom initial props in the dictionary below. // They will be passed down to the ViewController used by React Native. self.initialProps = @{}; return [super application:application didFinishLaunchingWithOptions:launchOptions]; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } @end ```


Android

Click To Expand

#### Have you converted to AndroidX? - [x] my application is an AndroidX application? - [x] 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 // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { buildToolsVersion = "33.0.0" minSdkVersion = 21 compileSdkVersion = 33 targetSdkVersion = 33 appCompatVersion = "1.4.2" googlePlayServicesLocationVersion = "21.0.1" RNMapboxMapsImpl = "mapbox" // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. ndkVersion = "23.1.7779620" } repositories { google() mavenCentral() } dependencies { classpath("com.android.tools.build:gradle") classpath("com.facebook.react:react-native-gradle-plugin") classpath("com.google.gms:google-services:4.3.14") classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.2") } } allprojects { repositories { mavenCentral() mavenLocal() // Required for react-native-background-geolocation maven { url("${project(':react-native-background-geolocation').projectDir}/libs") } maven { url 'https://developer.huawei.com/repo/' } // Required for react-native-background-fetch maven { url("${project(':react-native-background-fetch').projectDir}/libs") } maven { url 'https://api.mapbox.com/downloads/v2/releases/maven' authentication { basic(BasicAuthentication) } credentials { username = 'mapbox' password = '' } } mavenCentral { content { excludeGroup "com.facebook.react" } } } } ``` #### `android/app/build.gradle`: ```groovy apply plugin: "com.android.application" apply plugin: "com.facebook.react" apply plugin: "com.google.gms.google-services" apply plugin: "com.google.firebase.crashlytics" import groovy.json.JsonSlurper /** * This is the configuration block to customize your React Native Android app. * By default you don't need to apply any configuration, just uncomment the lines you need. */ react { /* Folders */ // The root of your project, i.e. where "package.json" lives. Default is '..' // root = file("../") // The folder where the react-native NPM package is. Default is ../node_modules/react-native // reactNativeDir = file("../node_modules/react-native") // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen // codegenDir = file("../node_modules/@react-native/codegen") // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js // cliFile = file("../node_modules/react-native/cli.js") /* Variants */ // The list of variants to that are debuggable. For those we're going to // skip the bundling of the JS bundle and the assets. By default is just 'debug'. // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. // debuggableVariants = ["liteDebug", "prodDebug"] /* Bundling */ // A list containing the node command and its flags. Default is just 'node'. // nodeExecutableAndArgs = ["node"] // // The command to run when bundling. By default is 'bundle' // bundleCommand = "ram-bundle" // // The path to the CLI configuration file. Default is empty. // bundleConfig = file(../rn-cli.config.js) // // The name of the generated asset file containing your JS bundle // bundleAssetName = "MyApplication.android.bundle" // // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' // entryFile = file("../js/MyApplication.android.js") // // A list of extra flags to pass to the 'bundle' commands. // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle // extraPackagerArgs = [] /* Hermes Commands */ // The hermes compiler command to run. By default it is 'hermesc' // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" // // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" // hermesFlags = ["-O", "-output-source-map"] } Project background_geolocation = project(':react-native-background-geolocation') apply from: "${background_geolocation.projectDir}/app.gradle" /** * Set this to true to Run Proguard on Release builds to minify the Java bytecode. */ def enableProguardInReleaseBuilds = true /** * The preferred build flavor of JavaScriptCore (JSC) * * 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:+' def getVersionFromNpm() { def inputFile = new File("$rootDir/../package.json") def packageJson = new JsonSlurper().parseText(inputFile.text) return packageJson["version"] } android { ndkVersion rootProject.ext.ndkVersion compileSdkVersion rootProject.ext.compileSdkVersion namespace "nl.ivn.routeapp" defaultConfig { applicationId "nl.ivn.routeapp" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 20021 versionName getVersionFromNpm() } signingConfigs { debug { storeFile file('debug.keystore') storePassword 'android' keyAlias 'androiddebugkey' keyPassword 'android' } release { if (project.hasProperty('IVN_NATUURBELEVING_RELEASE_STORE_FILE')) { storeFile file(IVN_NATUURBELEVING_RELEASE_STORE_FILE) storePassword IVN_NATUURBELEVING_RELEASE_STORE_PASSWORD keyAlias IVN_NATUURBELEVING_RELEASE_KEY_ALIAS keyPassword IVN_NATUURBELEVING_RELEASE_KEY_PASSWORD } } } buildTypes { debug { signingConfig signingConfigs.debug } release { // Caution! In production, you need to generate your own keystore file. // see https://reactnative.dev/docs/signed-apk-android. signingConfig signingConfigs.release minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" proguardFiles "${background_geolocation.projectDir}/proguard-rules.pro" } } } dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") implementation platform('com.google.firebase:firebase-bom:32.6.0') implementation 'com.google.firebase:firebase-messaging' implementation 'com.google.firebase:firebase-analytics' debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { exclude group:'com.squareup.okhttp3', module:'okhttp' } debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") if (hermesEnabled.toBoolean()) { implementation("com.facebook.react:hermes-android") } else { implementation jscFlavor } } apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle") ``` #### `android/settings.gradle`: ```groovy rootProject.name = 'IVN Natuur' apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' includeBuild('../node_modules/@react-native/gradle-plugin') ``` #### `MainApplication.java`: ```java package nl.ivn.routeapp; import android.app.Application; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; import com.facebook.react.defaults.DefaultReactNativeHost; import com.facebook.soloader.SoLoader; import java.util.List; public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new DefaultReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List packages = new PackageList(this).getPackages(); // Packages that cannot be autolinked yet can be added manually here, for example: // packages.add(new MyReactNativePackage()); return packages; } @Override protected String getJSMainModuleName() { return "index"; } @Override protected boolean isNewArchEnabled() { return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; } @Override protected Boolean isHermesEnabled() { return BuildConfig.IS_HERMES_ENABLED; } }; @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { // If you opted-in for the New Architecture, we load the native entry point for this app. DefaultNewArchitectureEntryPoint.load(); } ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); } } ``` #### `AndroidManifest.xml`: ```xml ```


Environment

Click To Expand

**`react-native info` output:** ``` System: OS: macOS 14.1.1 CPU: (10) arm64 Apple M1 Pro Memory: 336.23 MB / 16.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 16.18.0 path: ~/.nvm/versions/node/v16.18.0/bin/node Yarn: version: 1.22.19 path: ~/.nvm/versions/node/v16.18.0/bin/yarn npm: version: 9.8.1 path: ~/repos/ivn/natuurbeleving-app/node_modules/.bin/npm Watchman: version: 2023.01.23.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.11.3 path: /opt/homebrew/bin/pod SDKs: iOS SDK: Platforms: - DriverKit 23.0 - iOS 17.0 - macOS 14.0 - tvOS 17.0 - watchOS 10.0 Android SDK: API Levels: - "27" - "28" - "29" - "30" - "31" - "32" - "33" Build Tools: - 28.0.3 - 29.0.2 - 30.0.2 - 30.0.3 - 31.0.0 - 32.0.0 - 32.1.0 - 33.0.0 System Images: - android-24 | Google APIs ARM 64 v8a - android-25 | Google APIs ARM 64 v8a - android-29 | Intel x86 Atom_64 - android-29 | Google APIs Intel x86 Atom - android-30 | Google APIs ARM 64 v8a - android-32 | Google APIs ARM 64 v8a Android NDK: Not Found IDEs: Android Studio: 2021.1 AI-211.7628.21.2111.8092744 Xcode: version: 15.0.1/15A507 path: /usr/bin/xcodebuild Languages: Java: version: 11.0.11 path: /usr/bin/javac Ruby: version: 2.6.10 path: /usr/bin/ruby npmPackages: "@react-native-community/cli": Not Found react: installed: 18.2.0 wanted: 18.2.0 react-native: installed: 0.72.4 wanted: 0.72.4 react-native-macos: Not Found npmGlobalPackages: "*react-native*": Not Found Android: hermesEnabled: true newArchEnabled: false iOS: hermesEnabled: true newArchEnabled: false ``` - **Platform that you're experiencing the issue on**: - [x] iOS - [x] 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:** - `18.7.3` - **`Firebase` module(s) you're using that has the issue:** - `Messaging` - **Are you using `TypeScript`?** - `Y` & `4.9.3`


mikehardy commented 8 months ago

Basically there's a lot of information in here and some assertions on ideas about behavior but no code https://stackoverflow.com/help/minimal-reproducible-example