Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dagger2 non-@Nullable @Provides method

I'm at the beginning of use Dagger to my projects. I've made this modules:

@Module
public class FirebaseModule {

@Provides @Singleton
public FirebaseUser provideCurrentUser(){
    return FirebaseAuth.getInstance().getCurrentUser();
}

@Provides @Singleton
public DatabaseReference provideDatabaseReference(){
    return FirebaseDatabase.getInstance().getReference();
}

@Provides @Singleton
public FirebaseAuth provideFirebaseAuth(){
    return FirebaseAuth.getInstance();
}
}

and this:

@Module
public class AppModule
{
private HappyParkApp app;

public AppModule(HappyParkApp app) {
    this.app = app;
}

@Provides
public HappyParkApp providesApp()
{
return this.app;
}

@Provides
public Context getAppContext(){
    return this.app;
}
}

I've also made the component:

@Singleton
@Component(modules = {AppModule.class,
                      FirebaseModule.class})
public interface AppComponent {

    void inject(MainActivity activity);
}

and this is the appComponent implemented in the application:

public class HappyParkApp extends Application {

private AppComponent appComponent;
private static HappyParkApp instance = new HappyParkApp();
@Override
public void onCreate() {
    super.onCreate();
    createAppComponent();
}

public static HappyParkApp getInstance() {
    return instance;
}

public AppComponent createAppComponent() {
 if(appComponent == null){
     appComponent = DaggerAppComponent.builder()
             .appModule(new AppModule(this))
             .firebaseModule(new FirebaseModule()).build();
 }

 return appComponent;
}

}

so I've tried to to this in onCreate() method of MainActivity:

HappyParkApp.getInstance().createAppComponent().inject(this);

and this before:

 @Inject
FirebaseUser user;

@Inject
DatabaseReference reference;

@Inject
FirebaseAuth mAuth;

but I'm getting this error:

 Caused by: java.lang.NullPointerException: Cannot return null from a non-@Nullable @Provides method

at this line:

 HappyParkApp.getInstance().createAppComponent().inject(this);

and I don't know how to fix it: what is the error? Is this a wrong injection?

Thank you

like image 507
ste9206 Avatar asked May 03 '17 14:05

ste9206


2 Answers

Cannot return null from a non-@Nullable @Provides method

You try to provide null from a provider method that is not marked as @Nullable.

Have a look at getCurrentUser()

Returns the currently signed-in FirebaseUser or null if there is none.

So in case there is no signed in user, this will be null, making the following invalid...

@Provides @Singleton
public FirebaseUser provideCurrentUser(){
  return FirebaseAuth.getInstance().getCurrentUser(); // could be null!
}

So to fix it you have 2 options:

  • provide FirebaseAuth and grab the user in your application code, or
  • mark the provider as @Nullable

Which approach is better depends on your setup, but since you put the user in a @Singleton scoped component I recommend not providing the user, as it is likely to change within the lifetime of "Singleton".

Either move it into a different Scope (e.g. @UserScope or @PerUser) or just grab the user where you need it using FirebaseAuth.getCurrentUser(). You can ofc still provide FirebaseAuth.

Also read about nullability here.

like image 59
David Medenjak Avatar answered Oct 21 '22 09:10

David Medenjak


if you annotate your provider method with @Nullable and forget to use @Nullable whenever you want to use that object dagger will throw an error (is not nullable but is being provided by @Provides @android.support.annotation.Nullable)

so simply use if you provide a nullable object make sure to add @Nullable to every method that uses that object as a parameter

ex:

@Nullable
@Provides
static Object provideHomePost(MainActivity activity){
    return activity.getObject();
}
@Provides
static Presenter providePresenterFactory(@Nullable HomePost post) {
    return new CommentPresenterImpl(post);
}
like image 20
seyed Jafari Avatar answered Oct 21 '22 10:10

seyed Jafari