Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setPersistenceEnabled(true) crashes app

I’m creating my first Firebase App. One of its requirements is that it run when the network is not available. The Firebase guide states:

Enabling disk persistence allows our app to also keep all of its state even after an app restart. We can enable disk persistence with just one line of code. FirebaseDatabase.getInstance().setPersistenceEnabled(true); With disk persistence enabled, our synced data and writes will be persisted to disk across app restarts and our app should work seamlessly in offline situations.

Another requirement is to use Google Sign In. So in my MainActivity I check if the User is signed in, if not, I launch the SignInActivity. (The SignInActivity is from the Firebase examples.) The SignInActivity works, the user gets logged in, and MainActivity is launched for a second time. Now my app crashes on the code line FirebaseDatabase.getInstance().setPersistenceEnabled(true); with the following message:

Calls to setPersistenceEnabled() must be made before any other usage of FirebaseDatabase instance.

Now if I restart my app, the User is signed in, the SignInActivity is not launched, my app runs fine.

Any suggestions of how I avoid this crash after the User signs in?

As I was posting this question, I received a suggestion to relocate FirebaseDatabase.getInstance().setPersistenceEnabled(true); to my “Application class”. I get exactly the same result … SignInActivity starts, completes, and I get a crash on the setPersistenceEnabled.

Below is my MainActivity onCreate:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Calls to setPersistenceEnabled() must be made before any other usage of FirebaseDatabase instance.
    // Crash here upon returning from SignInActivity.  
    FirebaseDatabase.getInstance().setPersistenceEnabled(true);
    mFirebaseDbReference = FirebaseDatabase.getInstance().getReference();

    // Initialize Firebase Auth
    mFirebaseAuth = FirebaseAuth.getInstance();
    mFirebaseUser = mFirebaseAuth.getCurrentUser();
    if (mFirebaseUser == null) {
        // Not signed in, launch the Sign In activity
        Timber.tag("MainActivity").i("onCreate(): User not signed in, launching SignInActivity");
        startActivity(new Intent(this, SignInActivity.class));
        finish();

    } else {
        mUsername = mFirebaseUser.getDisplayName();
        Timber.tag("MainActivity").i("onCreate(): User \"%s\" signed in.", mUsername);
        if (mFirebaseUser.getPhotoUrl() != null) {
            mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();
        }
    } 
like image 715
Loren Avatar asked May 25 '16 21:05

Loren


3 Answers

A FirebaseApp is initialized by a ContentProvider so it is not initialized at the time onCreate() is called.

Get your FirebaseDatabase like this:

public class Utils {
    private static FirebaseDatabase mDatabase;

    public static FirebaseDatabase getDatabase() {
       if (mDatabase == null) {
          mDatabase = FirebaseDatabase.getInstance();
          mDatabase.setPersistenceEnabled(true);
       }
       return mDatabase;
    }

}

Then call Utils.getDatabase() from any activity you want.

Read more in this article

like image 80
Dan Alboteanu Avatar answered Nov 20 '22 02:11

Dan Alboteanu


I fixed this exception by using setPersistenceEnabled(true) in my Application class.

public class MApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        FirebaseDatabase.getInstance().setPersistenceEnabled(true);
    }
}

In AndroidManifest.xml, set the application name as MApplication:

<application
    android:name=".MApplication"
    ... />
like image 26
dknchris Avatar answered Nov 20 '22 00:11

dknchris


I was facing a similar problem and using a static variable seemed to resolve the issue for me. So at first my code looked something like this

@Override
protected void onCreate(Bundle savedInstanceState) {
    //..code

    FirebaseDatabase.getInstance().setPersistenceEnabled(true);
    FirebaseDatabase database = FirebaseDatabase.getInstance();

    //..code
}

and now it looks more like

static boolean calledAlready = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    //..code

    if (!calledAlready)
    {
        FirebaseDatabase.getInstance().setPersistenceEnabled(true);
        calledAlready = true;
    }

    FirebaseDatabase database = FirebaseDatabase.getInstance();

    //..code
}

Hope it helps!

like image 27
businesscasual Avatar answered Nov 20 '22 02:11

businesscasual