35 votes

setPersistenceEnabled (true) bloque l'application

Je suis de créer mon premier Firebase App. L'un de ses exigences, c'est qu'il s'exécuter lorsque le réseau n'est pas disponible. Le Firebase guide états:

L'activation de disque persistance permet à notre application pour aussi garder tous ses état, même après une application de redémarrer. Nous pouvons nous permettre de disque persistance avec une seule ligne de code. FirebaseDatabase.getInstance().setPersistenceEnabled(true); Avec disque persistance activé, nos données synchronisées et écrit seront enregistrées sur le disque d'application redémarre et notre application s'intègre parfaitement dans des situations hors ligne.

Une autre exigence est d'utiliser Google, connectez-vous. Donc, dans mon MainActivity - je vérifier si l'Utilisateur est connecté, sinon, je lance l' SignInActivity. (L' SignInActivity est à partir de la Firebase des exemples). L' SignInActivity fonctionne, l'utilisateur a ouvert une session, et MainActivity est lancé pour la deuxième fois. Maintenant, mon application se bloque sur le code de la ligne FirebaseDatabase.getInstance().setPersistenceEnabled(true); avec le message suivant:

Les appels à setPersistenceEnabled() doit être faite avant toute autre utilisation de FirebaseDatabase instance.

Maintenant, si je redémarre mon application, l'Utilisateur est connecté, l' SignInActivity n'est pas lancé, mon appli fonctionne très bien.

Toutes les suggestions de comment je éviter ce plantage après que l'Utilisateur se connecte?

Comme je l'ai été poster cette question, j'ai reçu une suggestion de déménager FirebaseDatabase.getInstance().setPersistenceEnabled(true); pour ma "classe d'Application". J'obtiens exactement le même résultat ... SignInActivity commence, se termine, et j'ai un crash sur l' setPersistenceEnabled.

Ci-dessous mon 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();
        }
    } 

52voto

Dan Alboteanu Points 1570

Un FirebaseApp est initialisé par un ContentProvider de sorte qu'il n'est pas initialisé au moment de l' onCreate() est appelé.

Obtenez votre FirebaseDatabase comme ceci:

public class Utils {
    private static FirebaseDatabase mDatabase;

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

}

Puis appelez Utils.getDatabase() de toute l'Activité pour l'utilisation de la Base de données.

N'oubliez pas de mettre compile 'com.google.firebase:firebase-database:...' dans la construction.gradle

Lire la suite dans cet article

48voto

dknchris Points 491

J'ai corrigé cette exception en utilisant setPersistenceEnabled(true) dans ma classe Application .

 public class MApplication extends Application {

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

Dans AndroidManifest.xml, définissez le nom de l'application sur MApplication:

 <application
    android:name=".MApplication"
    ... />
 

25voto

imakeApps Points 615

Je faisais face à un problème similaire et l’utilisation d’une variable statique a semblé résoudre le problème pour moi. Donc au début, mon code ressemblait à quelque chose comme ça

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

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

    //..code
}
 

et maintenant ça ressemble plus à

 static boolean calledAlready = false;

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

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

    FirebaseDatabase database = FirebaseDatabase.getInstance();

    //..code
}
 

J'espère que ça aide!

17voto

rkmax Points 3436

J'ai un peu tard mais aujourd'hui j'ai ce problème, j'ai résolu en ajoutant

 static {
    FirebaseDatabase.getInstance().setPersistenceEnabled(true);
}
 

à mon activité

3voto

tingyik90 Points 631

Pour moi, il est plus facile d'être manipulés par la création d'une catégorie distincte pour les Firebase. C'est parce que Firebase a sa propre instance et si vous l'utilisez en plus d'une activité, il y a la possibilité pour elle de se bloquer si vous appelez setPersistenceEnabled de nouveau dans une autre activité.

Une autre bonne chose est que vous pouvez passer votre contexte ou des paramètres dans le FirebaseHandler constructeur si nécessaire. Ou si vous avez d'emplacement fixe dans la base de données, ils peuvent être appelés facile sans .enfant("location") standard.

Exemple:

public class FirebaseHandler {

    // parameters
    private Context context;
    private String userKey;
    private DatabaseReference databaseReference;
    private static boolean isPersistenceEnabled = false;
    private static String fixedLocationA = "locationA";
    private static String fixedLocationB = "locationB";

    public FirebaseHandler(Context context, String userKey) {
        this.context = context;    // context can be used to call PreferenceManager etc.
        this.userKey = userKey;
        if (!isPersistenceEnabled) {
            FirebaseDatabase.getInstance().setPersistenceEnabled(true);
            isPersistenceEnabled = true;
        }
        databaseReference = FirebaseDatabase.getInstance().getReference().child(userKey);
    }

    public DatabaseReference getRefA() {
        return databaseReference.child(fixedLocationA);
    }

    public DatabaseReference getRefB() {
        return databaseReference.child(fixedLocationB);
    }
}

Cela peut ensuite être appelé à une Activité comme ci-dessous.

public class MyActivity extends AppCompatActivity {

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

        // get instance
        FirebaseHandler firebaseHandler = new FirebaseHander(this, "userKey");
        // to set value
        firebaseHandler.getRefA().setValue("value");

        // to set listener
        firebaseHandler.getRefB().addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                // TODO here....

                // also, can remove listener if required
                if (certain condition) {
                    firebaseHandler.getRefB().removeEventListener(this);
                }
            }
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X