-
Notifications
You must be signed in to change notification settings - Fork 4k
🐛 [firebase_messaging] "No Firebase App..." in background message handler #3520
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
Comments
Hi @rubenvereecken, Please see this link for more information and check if it's helpful to answer some of your questions. |
Facing the exact same issue. Need to update a sent message's delivery receipt when the notification is delivered. I am leaving notification payload empty and passing all the data with data payload. Intializing Firebase in main():
Then from myBackgroundMessageHandler calling _setMessageDelivered() which makes a call to Firestore:
Getting the error: Everything works as expected when the app is in the foreground. One possible solution can be to check |
@darshankawar that would work, though it is a very different use case from mine. I very much want to do a bit of background processing rather than responding to the user opening the app again - they might never. Opportunistic processing of course because I know data messages might not come through, but all the same. That's why I'm talking explicitly about data-only messages here. They could be entirely stand-alone without a displayed notification. @rahuldubey093 It seems like you have a similar use case to mine, meaning that it's probably not such a rare use case. It's a clever workaround to only kick back into gear when the app is un-paused but something tells me that won't work. I have a feeling that the background data message handler is fundamentally different from the foreground data message handler in that it is started in a different "thread", with no shared memory space, as I've seen with Isolates. I'm pretty sure it's an Isolate. If that's the case it means that communication to the rest of your app needs to be done through some other means - some kind of shared messaging queue. But I'm too new to Isolates to know what the best solution is here. So my question to the developers then: Is my presumption correct? Are background data message handlers run in an Isolate? If so, what is the recommended way to communicate to the rest of the app? Is the rest of the app even still running, if that question even makes sense? So if I manage to get a message from the Isolate to the "main app", could the main app now do a network request for example? Or is the "main app" paused? |
I tried it but it doesn't work, there are some other errors. @rubenvereecken looks like what you said about isolates is true, when executing code inside myBackgroundMessageHandler() it seems like the code is executed independently and has only access to whatever is inside the myBackgroundMessageHandler() method. When I figured this out, I thought maybe accessing Cloud Firestore via the REST API will work, so I tried it and it works! So you can perform operations on the database using the REST API via HTTP calls. My _setMessageDelivered() method looks like this now. I am performing REST API PATCH to update selective fields in the database:
Maybe it can help as a temporary solution. |
@rahuldubey093 That's really neat and thanks for confirming part of my suspicion! I'll still be on the hunt for a solution to communicate to the rest of the app as one of the main consequences of data messages is pulling in data or doing something on the background. I'll see if there's a way to communicate in-memory especially but perhaps I can fold it into our persistent storage. |
I'm here too and figured it must be an isolate. Was discussing this here with some ideas: |
I ve managed to run firestore in the background message handler, by registering the Firebase core and Firestore plugins in Application.kt and then initializing Firebase in the background message handler isolate. Here is the code for the respected files - package com.example.yourpackagename
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin
import io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin
import io.flutter.plugins.firebase.firestore.FlutterFirebaseFirestorePlugin
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this);
}
override fun registerWith(registry: PluginRegistry?) {
io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin"));
io.flutter.plugins.firebase.firestore.FlutterFirebaseFirestorePlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebase.firestore.FlutterFirebaseFirestorePlugin"));
//This is optional if you want to use shared Preferences as well
io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin"));
}
} and then wherever you have declared the callbacks for push notification manager. main.dart or notifications.dart - Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
print("myBackgroundMessageHandler fired");
if (message.containsKey('data')) {
// Handle data message
final dynamic data = message['data'];
await Firebase.initializeApp();
print("Firebase initialized");
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
//Do Anything with firestore now
//Similarly any other flutter fire plugin can be used here after registering it in the Application.kt
}
} |
Bug report
Describe the bug
My background message handler always throws the error
Closer inspection of the stacktrace revealed that it threw because it relies on code that relies on the
FirebaseAuth.instance
.Steps to reproduce
Steps to reproduce the behavior:
Expected behavior
I would expect to be able to use Firebase in the background message handler. This seems not to be the case and I'd like to figure out what the limitations are. Is this expected behavior? Can I get around it by initializing firebase inside the message handler? Globals don't seem to be shared - a separate thread or isolate then? If this is indeed expected (the docs don't really say as much) - what is the advised way to pass messages to other parts of the app, say so that data can be displayed when it opens again? Or is there no way to communicate back to "the main thread"?
Flutter dependencies
The text was updated successfully, but these errors were encountered: