ste9206
ste9206

Reputation: 1892

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

Upvotes: 10

Views: 14202

Answers (2)

seyed Jafari
seyed Jafari

Reputation: 1265

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);
}

Upvotes: 6

David Medenjak
David Medenjak

Reputation: 34532

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.

Upvotes: 16

Related Questions