Reputation: 594
I'm working on an App that uses both Firebase Messaging and Room database.
This is how the db is initialized
public static AppDatabase getInstance(final Context appContext) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(appContext, AppDatabase.class, "dbname.db")
// prepopulate the database after onCreate was called
.addCallback(rdc)
.build();
}
return INSTANCE;
}
Somewhere on MainActivity
the first call to AppDatabase
is made and the database is instantiated, all is working fine and dandy!
Now the problem starts when the user kill
the app...
For the sake of simplicity think of this App like Whatsapp... the application got killed but the service (MyFirebaseMessagingService)
that is listening for messages is still running (as it should).
When a new message arrives and MyFirebaseMessagingService
tries to save it to the database with a call to AppDatabase.getInstance()
a crash will occur since the initial context
reference on witch the database was created no longer exists because the application was killed.
Searching on how to solve this I learned that every service this
is actually derived from context
so I immediately tried to use the MyFirebaseMessagingService
context to initialize the database, however, MyFirebaseMessagingService::onCreate
where you really have access to the service context don't get fired until the first message arrives
The only solution I can think of is creating a completely new service, bindService()
it to the MainActivity, and use that new service context to create the AppDatabase instance... but it seems completely overkill.
So my question is, how can initialize the Room Database in a way that MyFirebaseMessagingService
can still use it even if the App was killed?
Upvotes: 12
Views: 3767
Reputation: 10254
Since FirebaseMessagingService
is a service we should have getApplicationContext()
there, you should use that to create an instance of your dB and do the necessary operations,
The other options are to create a service or write a custom broadcast receiver.
Upvotes: 0
Reputation: 2767
getApplicationContext()
is not available in the constructor function. But it's available inside onStartCommand()
function. I think that's a good place to build/open the database in a service.
Upvotes: 2
Reputation: 150
First: from a system context (NOTIFICATION_SERVICE) you are trying to use Room that uses the app context to access or create the database. But the app context might be null in that moment. Maybe just because the app got killed. So you get a nice crash.
Second, some logs would be nice. With the crash. It might keep people from guessing.
Third: (Again a guess) Maybe you should try Work manager. Something like: you receive data > start work. Will run reliably and do not have to run right in that moment. A great place to start here
Upvotes: -1