react-native-firebase
react-native-firebase copied to clipboard
[🐛] 🔥 @react-native-firebase/messaging (Android) - Messaging() gets the wrong ReactContext when there is another Activity instantiated by ReactInstanceManager?
UPDATED:
Hi there, Sorry for my interpretation, as you said, it's difficult to spot and verify fix using only my description So I created a mini-repo to reproduce this error, please take a look https://github.com/longb1997/rn-fcm-issue-7768 Thank you for your time, I really appreciate it
Issue
Hello, first of all, thank you for the wonderful library. In my app chat. I have an "Bubble Chat" which uses Bubbles API. It will show Bubbles when it receives new notifications. And when you press on the bubble, then will display a window that runs startReactApplication display conversation screen (like Messenger).
The problem is that after pressing the Bubble, messaging() function in my Main App code doesn't works anymore, but if I use these codes in Bubble Chat code (separate from MainApp code) it still works. But if i delete Main App from Recent Apps, then reopen, from now on it work fine until I press a new bubble => start new conversation screen. (Ah sh*t, here we go again) => So i think when a react app start, this lib will use the most recent ReactContext of the app that just started.
Since messaging() in Main App was not working, it caused all my messaging().onNotificationOpenedApp, messaging().onMessage, messaging().getInitialNotification() to not working anymore Thanks for helping me
i will provide some code here:
Project Files
BubbleActivity.kt:
class BubbleActivity : AppCompatActivity(), DefaultHardwareBackBtnHandler, PermissionAwareActivity {
private lateinit var reactRootView: ReactRootView
private lateinit var reactInstanceManager: ReactInstanceManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(null)
SoLoader.init(this, false)
val channelId = intent.getStringExtra("channelId")
val initialProps = Bundle()
if (channelId != null) {
initialProps.putString("channelId", channelId)
}
reactRootView = ReactRootView(this)
val packages: List<ReactPackage> = PackageList(application).packages
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(MyReactNativePackage())
// Remember to include them in `settings.gradle` and `app/build.gradle` too.
reactInstanceManager = ReactInstanceManager.builder()
.setApplication(application)
.setCurrentActivity(this)
.setBundleAssetName("index2.android.bundle") => This Bubble has seperated code with MainApp, and it bundle will be generated before build.
.setJSMainModulePath("index2") => entry file seperated with MainApp(index.js)
.addPackages(packages)
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setJavaScriptExecutorFactory(HermesExecutorFactory())
.setInitialLifecycleState(LifecycleState.RESUMED)
.build()
reactRootView.startReactApplication(reactInstanceManager, "chathead", initialProps) => It will start an ReactApp after pressed Bubble
setContentView(reactRootView)
}
override fun onNewIntent(intent: Intent) {
setIntent(intent)
super.onNewIntent(intent)
}
override fun invokeDefaultOnBackPressed() {
onBackPressedDispatcher.onBackPressed()
}
override fun onPause() {
super.onPause()
reactInstanceManager.onHostPause(this)
}
override fun onResume() {
super.onResume()
reactInstanceManager.onHostResume(this, this)
}
override fun onDestroy() {
super.onDestroy()
reactInstanceManager.onHostDestroy(this)
reactRootView.unmountReactApplication()
}
override fun onBackPressed() {
reactInstanceManager.onBackPressed()
onBackPressedDispatcher.onBackPressed()
}
}
And this is now in MainApp, where i use messaging() for handle notification
NotificationHandler.tsx
const NotificationHandler = memo(
() => {
// action press notify when app in background or active
useEffect(() => {
let unsubscribeOnNotificationOpenedApp: any = null;
let unsubscribe: any = null;
setTimeout(() => {
unsubscribeOnNotificationOpenedApp = messaging().onNotificationOpenedApp(value => {
return _.debounce(handleMessage, 300)(value);
});
unsubscribe = messaging().onMessage(message => {
return require('lodash').debounce(handleRemoteMessage, 300)(message);
});
}, 1000);
if (Platform.OS === 'android') {
messaging()
.getInitialNotification()
.then(value => {
return require('lodash').debounce(handleGetInitNotification, 1500)(value);
});
}
return () => {
unsubscribe && unsubscribe();
unsubscribeOnNotificationOpenedApp && unsubscribeOnNotificationOpenedApp();
};
}, []);
return null;
},
() => true
)
Then i used it like a component in MainApp
###App.tsx
<>
<NotificationHandler />
<Routes />
</>
package.json
:
"react-native": "0.71.13",
"@react-native-firebase/analytics": "^18.3.0",
"@react-native-firebase/app": "^18.6.1",
"@react-native-firebase/crashlytics": "^18.3.0",
"@react-native-firebase/messaging": "^18.6.1",
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? - [x] I am using the NPM package
jetifier
for react-native compatibility?
android/build.gradle
:
buildscript {
ext {
buildToolsVersion = "33.0.0"
minSdkVersion = 23
compileSdkVersion = 33
targetSdkVersion = 33
// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
ndkVersion = "23.1.7779620"
playServicesLocationVersion = "21.0.1"
kotlinVersion = '1.8.0'
kotlin_version = '1.8.0'
}
repositories {
google()
mavenCentral()
maven { url "https://jitpack.io" }
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("com.facebook.react:react-native-gradle-plugin")
// Make sure that you have the Google services Gradle plugin dependency
classpath("com.google.gms:google-services:4.3.15")
classpath('com.google.firebase:firebase-crashlytics-gradle:2.9.9')
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
android/app/build.gradle
:
apply plugin: "com.android.application"
apply plugin: "com.google.gms.google-services" // <- Add this line
apply plugin: "com.facebook.react"
apply plugin: 'kotlin-android'
import com.android.build.OutputFile
/**
* 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"
bundleCommand = "webpack-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"]
}
/**
* Set this to true to create four separate APKs instead of one,
* one for each native architecture. This is useful if you don't
* use App Bundles (https://developer.android.com/guide/app-bundle/)
* and want to have separate APKs to upload to the Play Store.
*/
def enableSeparateBuildPerCPUArchitecture = false
/**
* 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 localPropertiesFile = rootProject.file('local.properties')
def localProperties = new Properties()
localProperties.load(new FileInputStream(localPropertiesFile))
/**
* Private function to get the list of Native Architectures you want to build.
* This reads the value from reactNativeArchitectures in your gradle.properties
* file and works together with the --active-arch-only flag of react-native run-android.
*/
def reactNativeArchitectures() {
def value = project.getProperties().get("reactNativeArchitectures")
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
}
android {
ndkVersion rootProject.ext.ndkVersion
compileSdkVersion rootProject.ext.compileSdkVersion
namespace "com.example.app"
defaultConfig {
applicationId "com.example.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 8409223
versionName "7.3.3"
multiDexEnabled true
buildConfigField("String", "SECRET_KEY", localProperties["SECRET_KEY"])
}
// for react-native-twilio-video-webrtc
dexOptions {
jumboMode true
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include (*reactNativeArchitectures())
}
}
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
}
// compileOptions {
// sourceCompatibility JavaVersion.VERSION_17
// targetCompatibility JavaVersion.VERSION_17
// }
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.debug
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
// 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
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
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 =
defaultConfig.versionCode * 1000 + versionCodes.get(abi)
}
}
}
}
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
implementation 'com.google.android.play:core:1.10.2'
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
// for firebase
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:firebase-bom:32.5.0"))
// for HW keyboard
implementation project(':react-native-hw-keyboard-event')
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
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
}
// add kotlin version
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.21"
implementation "androidx.core:core-ktx:1.8.0"
// more
// If your app supports Android versions before Ice Cream Sandwich (API level 14)
implementation 'com.facebook.fresco:animated-base-support:1.3.0'
implementation 'com.facebook.fresco:fresco:2.6.0'
// For animated GIF support
implementation 'com.facebook.fresco:animated-gif:2.5.0'
// For WebP support, including animated WebP
implementation 'com.facebook.fresco:animated-webp:2.5.0'
implementation 'com.facebook.fresco:webpsupport:2.5.0'
// For WebP support, without animations
implementation 'com.facebook.fresco:webpsupport:2.5.0'
// for react-natie-video
implementation "androidx.appcompat:appcompat:1.6.1"
// using for geo location services
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation "androidx.cardview:cardview:1.0.0"
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
android/settings.gradle
:
rootProject.name = 'chatapp'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':react-native-hw-keyboard-event'
project(':react-native-hw-keyboard-event').projectDir = new File(settingsDir, '../node_modules/react-native-hw-keyboard-event/android')
include ':app'
includeBuild('../node_modules/react-native-gradle-plugin')
MainApplication.java
:
package com.example.app;
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;
import cl.json.ShareApplication;
import org.wonday.orientation.OrientationActivityLifecycle;
public class MainApplication extends Application implements ReactApplication, ShareApplication {
private final ReactNativeHost mReactNativeHost =
new DefaultReactNativeHost(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());
packages.add(new BubblePackage());
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();
registerActivityLifecycleCallbacks(OrientationActivityLifecycle.getInstance());
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());
}
@Override
public String getFileProviderAuthority() {
return "com.example.app";
}
}
AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<!-- Request Permission for Image Picker -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:node="replace" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission
android:name="android.permission.ACCESS_MEDIA_LOCATION"
tools:node="replace" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- RN-FETCH-BLOB -->
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
tools:node="replace" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- remove AD_ID permission -->
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>
<!-- Needed only if your app communicates with already-paired Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!--bibo01 : hardware option-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.microphone"
android:required="false" />
<!-- for permission -->
<application
android:name=".MainApplication"
android:allowBackup="false"
android:allowNativeHeapPointerTagging="false"
android:exported="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:replace="android:allowBackup,android:theme">
<!-- android:hardwareAccelerated="false" if true it's crash on some devices android-->
<activity android:name=".BubbleActivity"
android:resizeableActivity="true"
android:allowEmbedded="true"
android:launchMode="singleTop"
tools:targetApi="n" />
<activity
android:name=".MainActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize"
>
<!-- Note that if you set android:windowSoftInputMode to adjustResize or adjustPan,
only keyboardDidShow and keyboardDidHide events will be available on Android-->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
</intent-filter>
<!-- This is for everything else -->
<intent-filter android:label="ChatApp" android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="com.example.app"/>
<data android:scheme="message"/>
</intent-filter>
<intent-filter android:label="ChatApp" android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="base-message"/>
</intent-filter>
<intent-filter android:label="ChatApp" android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<!--TODO: Add this filter, if you want support opening urls into your app-->
<data android:scheme="https" android:pathPrefix="/" android:host="*.chatapp"/>
</intent-filter>
<!--TODO: Add this filter, if you want to support sharing text into your app-->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/*"/>
</intent-filter>
<!--TODO: Add this filter, if you want to support sharing any type of files-->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="*/*"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="*/*"/>
</intent-filter>
<!--TODO: Add this filter, if you want to support sharing videos into your app-->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="video/*"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="video/*"/>
</intent-filter>
<!--TODO: Add this filter, if you want to support sharing any type of files-->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="*/*"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="*/*"/>
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@mipmap/ic_notification" tools:replace="android:resource"/>
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/primary" tools:replace="android:resource"/>
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/base_default_channel"
tools:replace="android:value"/>
<!-- https://firebase.google.com/docs/cloud-messaging/android/client#prevent-auto-init -->
<!-- This for prevent generating new token -->
<meta-data
android:name="firebase_messaging_auto_init_enabled"
android:value="false"
tools:replace="android:value"/>
<meta-data
android:name="firebase_analytics_collection_enabled"
tools:replace="android:value"
android:value="false"/>
<!-- React-Native-Share -->
<provider
tools:replace="android:exported"
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:multiprocess="true"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"
tools:replace="android:resource"/>
</provider>
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="true"
tools:replace="android:value"/>
<uses-library
android:name="org.apache.http.legacy"
android:required="false"/>
</application>
</manifest>
Environment
Click To Expand
react-native info
output:
System:
OS: macOS 14.4.1
CPU: (4) x64 Intel(R) Core(TM) i3-8100 CPU @ 3.60GHz
Memory: 25.89 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.20.2 - /usr/local/bin/node
Yarn: 1.22.22 - /usr/local/bin/yarn
npm: 10.5.0 - /usr/local/bin/npm
Watchman: 2024.04.15.00 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.15.2 - /usr/local/lib/ruby/gems/3.3.0/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 23.4, iOS 17.4, macOS 14.4, tvOS 17.4, visionOS 1.1, watchOS 10.4
Android SDK: Not Found
IDEs:
Android Studio: 2023.2 AI-232.10300.40.2321.11567975
Xcode: 15.3/15E204a - /usr/bin/xcodebuild
Languages:
Java: 17.0.11 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.2.0 => 18.2.0
react-native: 0.71.13 => 0.71.13
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found```
<!-- change `[ ]` to `[x]` to select an option(s) -->
- **Platform that you're experiencing the issue on**:
- [ ] 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:**
"@react-native-firebase/analytics": "^18.3.0",
"@react-native-firebase/app": "^18.6.1",
"@react-native-firebase/crashlytics": "^18.3.0",
"@react-native-firebase/messaging": "^18.6.1",
- **`Firebase` module(s) you're using that has the issue:**
"@react-native-firebase/messaging": "^18.6.1",
- **Are you using `TypeScript`?**
- YES
</p>
</details>
<!-- Thanks for reading this far down ❤️ -->
<!-- High quality, detailed issues are much easier to triage for maintainers -->
<!-- For bonus points, if you put a 🔥 (:fire:) emojii at the start of the issue title we'll know -->
<!-- that you took the time to fill this out correctly, or, at least read this far -->
---
- 👉 Check out [`React Native Firebase`](https://twitter.com/rnfirebase) and [`Invertase`](https://twitter.com/invertaseio) on Twitter for updates on the library.
If you need me to provide more information, feel free to ask me @mikehardy Thank you so much
Hey there - two thoughts,
1- can you use current versions please, just to make sure we're not chasing ghosts? 2- version skew within react-native-firebase packages violates our versioning expectations --> https://invertase.io/blog/react-native-firebase-versioning - all the same all the time is the rule
"react-native": "0.71.13",
"@react-native-firebase/analytics": "^18.3.0",
"@react-native-firebase/app": "^18.6.1",
"@react-native-firebase/crashlytics": "^18.3.0",
"@react-native-firebase/messaging": "^18.6.1",
For troubleshooting:
So i think when a react app start, this lib will use the most recent ReactContext of the app that just started.
What makes you think that? I suggest using System.out.println or similar in the native code (yours and you can add it easily to react-native-firebase/messaging) to log out exactly what context is in use to see if they are different and/or incorrect.
In general it sounds like inference on a problem but without direct proof, and direct proof / ability to fix + test fixes will be difficult in the context of a large app whereas a https://stackoverflow.com/help/minimal-reproducible-example that was purpose built to expose the issue in could make it trivial to spot + verify fix
For troubleshooting:
So i think when a react app start, this lib will use the most recent ReactContext of the app that just started.
What makes you think that? I suggest using System.out.println or similar in the native code (yours and you can add it easily to react-native-firebase/messaging) to log out exactly what context is in use to see if they are different and/or incorrect.
In general it sounds like inference on a problem but without direct proof, and direct proof / ability to fix + test fixes will be difficult in the context of a large app whereas a https://stackoverflow.com/help/minimal-reproducible-example that was purpose built to expose the issue in could make it trivial to spot + verify fix
I think so because if I copy notificationHandler's code and use in Bubble code, messages() works properly in Bubble code
MainApp uses index.js entry file, Bubble uses index2.js entry file, each file leads to its own folder in the source code
Edit: I put Log in onReceive inside ReactNativeFirebaseMessagingReceiver.java, it is the same context. But I don't know why messaging() code only runs in Bubble Code after opening the Bubble screen. If I close Bubble and close the app in recent apps. Then use it normally without open Bubble it works normally
Hey there - two thoughts,
1- can you use current versions please, just to make sure we're not chasing ghosts? 2- version skew within react-native-firebase packages violates our versioning expectations --> https://invertase.io/blog/react-native-firebase-versioning - all the same all the time is the rule
"react-native": "0.71.13", "@react-native-firebase/analytics": "^18.3.0", "@react-native-firebase/app": "^18.6.1", "@react-native-firebase/crashlytics": "^18.3.0", "@react-native-firebase/messaging": "^18.6.1",
my bad, thanks for your reply. I just updated all React-native-firebase to the latest version (19.2.2). But the result is still the same.
<activity android:name=".BubbleActivity" android:resizeableActivity="true" android:allowEmbedded="true" tools:targetApi="n" />
I updated BubbleActivity in AndroidManifest, when I open MainApp without closing Bubble, it looks like messaging() "thinks" MainApp is not in foreground
In general it sounds like inference on a problem but without direct proof, and direct proof / ability to fix + test fixes will be difficult in the context of a large app whereas a https://stackoverflow.com/help/minimal-reproducible-example that was purpose built to expose the issue in could make it trivial to spot + verify fix
In general it sounds like inference on a problem but without direct proof, and direct proof / ability to fix + test fixes will be difficult in the context of a large app whereas a https://stackoverflow.com/help/minimal-reproducible-example that was purpose built to expose the issue in could make it trivial to spot + verify fix
Hi there, Sorry for my interpretation, as you said, it's difficult to spot and verify fix using only my description So I created a mini-repo to reproduce this error, please take a look https://github.com/longb1997/rn-fcm-issue-7768 Thank you for your time, I really appreciate it
if you have any confusion, please tell me @mikehardy Thank you very much
Same issue :(
@mikehardy thanks for labeling it, do you plan to fix this issue in the future? p/s: I'm not urging you, I'm just posting a comment to avoid bots closing this post because it's inactive xD Thank you
Hi, do you have any updates on this (or plans?)
hello, do you have any updates on this?
hello, do you have any updates on this?