How can I make it possible to pass database Instance to the MyFirebaseMessagingService
class which extends FirebaseMessagingService
so that I can save data
payload locally?
Note: I already setup dagger 2 in my app, it's working perfectly.
Below is MyFirebaseMessagingService
class:
class MyFirebaseMessagingService @Inject constructor(exampleOneDao: ExampleOneDao?) : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
//need db instance to store data payload locally (Room)
}
}
And below is the AppModule
class of Dagger 2
@Module(includes = arrayOf(ViewModelModule::class))
class AppModule() {
// --- DATABASE INJECTION ---
@Provides
@Singleton
internal fun provideDatabase(application: Application): MyDatabase {
return Room.databaseBuilder(application,
MyDatabase::class.java, "MyDatabase.db")
.build()
}
@Provides
@Singleton
internal fun provideExampleOneDao(database: MyDatabase): ExampleOneDao {
return database.exampleOneDao()
}
@Provides
@Singleton
internal fun provideMyFirebaseMessagingService(exampleOneDao:
ExampleOneDao): MyFirebaseMessagingService {
return MyFirebaseMessagingService(exampleOneDao)
}
}
Is it possible to provide database and dao to MyFirebaseMessagingService
class?
I tried above method to provide exampleOneDao
to the MyFirebaseMessagingService
class, but it throws the following Exception
MyFirebaseMessagingService: java.lang.InstantiationException: java.lang.Class<com.example.user.app.firebase.messaging.MyFirebaseMessagingService> has no zero argument constructor
Thank You.
For sending FCM notification payload you can use Firebase Cloud Messaging Tool in firebase console. And click on Send your first message. Then enter the Title and body field. If you wish to send it to a particular device then click on Send test message and enter the FCM registration token.
On initial startup of your app, the FCM SDK generates a registration token for the client app instance. If you want to target single devices or create device groups, you'll need to access this token by extending FirebaseMessagingService and overriding onNewToken .
Sending Notifications using Firebase Cloud Messaging UI Step 1, Go to the Firebase console. Under Engage, go to Cloud Messaging. We can use this tool to send out notifications to a specific group, device, or topic. Click on “Send your first message” and enter a title and text for the notification.
Finally got the solution from this link: https://github.com/googlesamples/android-architecture-components/issues/253
As MyFirebaseMessagingService
is a Service
class, so for injection in Service
class, Dagger provides a way through which we can inject dependencies into Service class. Below are the steps to enable injection in service class:
1) Make Application implements HasServiceInjector and inject a DispatchingAndroidInjector for services.
public class App extends Application implements HasActivityInjector, HasServiceInjector {
@Inject
DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
// Add this line
@Inject
DispatchingAndroidInjector<Service> dispatchingServiceInjector;
@Override
public void onCreate() {
super.onCreate();
AppInjector.init(this);
}
@Override
public AndroidInjector<Activity> activityInjector() {
return dispatchingActivityInjector;
}
// override this method after implementing HasServiceInjector
@Override
public AndroidInjector<Service> serviceInjector() {
return dispatchingServiceInjector;
}
}
2) Create a new module to perform injection over your services.
@Module
abstract class ServiceBuilderModule {
// for my case, the service class which needs injection is MyFirebaseMessagingService
@ContributesAndroidInjector
abstract MyFirebaseMessagingService contributeMyFirebaseMessagingService();
}
3) Register your new module in your application's component.
@Component(modules = {
AndroidSupportInjectionModule.class,
AppModule.class,
ActivityBuilderModule.class,
// Need to define previously created module class here
ServiceBuilderModule.class
})
@Singleton
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(App application);
AppComponent build();
}
void inject(App app);
}
4) And finally, override method onCreate of the service adding AndroidInjection.inject(this).
public class MyFirebaseMessagingService extends FirebaseMessagingService {
//So now we are able to inject here same as we do in Activity. No need for constructor injection
@Inject ExampleOneDao exampleOneDao
// Override this method first
@Override
public void onCreate() {
AndroidInjection.inject(this);
super.onCreate();
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// use your dao here to store remoteMessage data payload into your database, e.g exampleOneDao.save(somethingHere)
}
}
Here is the Kotlin implementation:
Application.kt
@Inject
lateinit var dispatchingServiceInjector: DispatchingAndroidInjector<Service>
override fun serviceInjector(): AndroidInjector<Service> {
return dispatchingServiceInjector
}
Module.kt
@Module
abstract class FirebaseServiceModule {
@ContributesAndroidInjector
abstract fun contributeMyFirebaseMessengingService(): MyFirebaseMessengingService
}
Component.kt
@Component(modules = [FirebaseServiceModule::class])
interface Component {
...
}
MyFirebaseMessengingService.kt
override fun onCreate() {
AndroidInjection.inject(this);
super.onCreate()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With