reglas con auth autenticacion firebase firebase-database firebase-authentication

con - firebase rules auth



aplicaciĆ³n setPersistenceEnabled(true) crashes (17)

Estoy creando mi primera aplicación de Firebase. Uno de sus requisitos es que se ejecute cuando la red no esté disponible. La guía de Firebase dice:

Al habilitar la persistencia del disco, nuestra aplicación también puede mantener todo su estado incluso después de reiniciar la aplicación. Podemos habilitar la persistencia del disco con solo una línea de código. FirebaseDatabase.getInstance (). SetPersistenceEnabled (true); Con la persistencia de disco habilitada, nuestros datos y escrituras sincronizados se mantendrán en el disco durante los reinicios de la aplicación y nuestra aplicación debería funcionar sin problemas en situaciones fuera de línea.

Otro requisito es utilizar Google Iniciar sesión. Por lo tanto, en mi actividad principal MainActivity si el usuario está registrado, si no es así, SignInActivity . ( SignInActivity es de los ejemplos de Firebase.) SignInActivity funciona, el usuario MainActivity sesión y MainActivity se inicia por segunda vez. Ahora mi aplicación se bloquea en la línea de código FirebaseDatabase.getInstance().setPersistenceEnabled(true); con el siguiente mensaje:

Las llamadas a setPersistenceEnabled () deben realizarse antes de cualquier otro uso de la instancia de FirebaseDatabase.

Ahora, si reinicio mi aplicación, el usuario SignInActivity , SignInActivity no se inicia, mi aplicación funciona bien.

¿Alguna sugerencia de cómo evitar este bloqueo después de que el usuario inicie sesión?

Mientras publicaba esta pregunta, recibí una sugerencia para reubicar FirebaseDatabase.getInstance().setPersistenceEnabled(true); a mi "clase de aplicación". Obtengo exactamente el mismo resultado ... SignInActivity inicia, completa y obtengo un bloqueo en setPersistenceEnabled .

A continuación está mi 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(); } }


Asegúrate de que .setpersistenceenabled (true) no esté sucediendo dos veces, mientras que inicie sesión en Google en tu caso, se debe llamar a second care setPersistenceEnabled (true) antes de que cualquier instancia de firebase llamada esto resuelva mi problema.


Crea una clase llamada Util.java

y agregue el siguiente código

public class Util { private static FirebaseDatabase mData; public static FirebaseDatabase getDatabase() { if (mData == null) { mData = FirebaseDatabase.getInstance(); mData.setPersistenceEnabled(true); } return mData; } }

Ahora reemplace FirebaseDatabase.getIntance () con Util.getDatabase () cada vez en cada actividad. ¡Llamar solo una vez recibirá el error!


El mensaje de error describe el problema:

Las llamadas a setPersistenceEnabled () deben realizarse antes de cualquier otro uso de la instancia de FirebaseDatabase.

La solución a este problema se describe en la documentación: como en SDK 2.x, la persistencia del disco debe estar habilitada antes de que se realicen otras llamadas a la base de datos.

FirebaseDatabase.getInstance().setPersistenceEnabled(true);

https://firebase.google.com/support/guides/firebase-android


Estaba enfrentando el mismo problema. Cambié el código como abajo.

ANTES (Causando Crash)

var rootRef = FIRDatabase.database().reference() override func viewDidLoad() { super.viewDidLoad() FIRDatabase.database().persistenceEnabled = true }

DESPUÉS (Bloqueo resuelto)

var rootRef:FIRDatabaseReference! override func viewDidLoad() { super.viewDidLoad() FIRDatabase.database().persistenceEnabled = true rootRef = FIRDatabase.database().reference() }


Lo resolvió haciendo que la referencia de Firebase sea un campo de clase estático como este:

public class MainActivity extends AppCompatActivity private static FirebaseDatabase fbDatabase; @Override protected void onCreate(Bundle savedInstanceState) { if(fbDatabase == null) { fbDatabase = FirebaseDatabase.getInstance(); fbDatabase.setPersistenceEnabled(true); }

No es problema crear nuevas referencias de Firebase (sin setPersistenceEnabled (true)) en otras actividades también.


Me enfrentaba a un problema similar y el uso de una variable estática parecía resolver el problema para mí. Así que al principio mi código se veía algo como esto

@Override protected void onCreate(Bundle savedInstanceState) { //..code FirebaseDatabase.getInstance().setPersistenceEnabled(true); FirebaseDatabase database = FirebaseDatabase.getInstance(); //..code }

y ahora se parece más a

static boolean calledAlready = false; @Override protected void onCreate(Bundle savedInstanceState) { //..code if (!calledAlready) { FirebaseDatabase.getInstance().setPersistenceEnabled(true); calledAlready = true; } FirebaseDatabase database = FirebaseDatabase.getInstance(); //..code }

¡Espero eso ayude!


Mordí tarde, pero hoy recibí este problema, lo resolví añadiendo

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

a mi actividad


No recomendaría usar Application para almacenar los datos porque, como está escrito en CodePath

Siempre hay datos e información que se necesita en muchos lugares dentro de su aplicación. Esto podría ser un token de sesión, el resultado de un cálculo costoso, etc. Podría ser tentador usar la instancia de la aplicación para evitar la sobrecarga de pasar objetos entre actividades o mantenerlas en almacenamiento persistente.

Sin embargo, nunca debe almacenar datos de instancias mutables dentro del objeto Aplicación porque si supone que sus datos permanecerán allí, su aplicación se bloqueará inevitablemente en algún momento con una NullPointerException. No se garantiza que el objeto de la aplicación permanezca en la memoria para siempre, será asesinado. Contrario a la creencia popular, la aplicación no se reiniciará desde cero. Android creará un nuevo objeto Aplicación e iniciará la actividad donde el usuario estaba antes para dar la ilusión de que la aplicación nunca se mató en primer lugar.

Esa es la razón por la que recomendaría usar un Singleton como este:

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

solo úsalo en tu código y luego

private FirebaseDatabase fdb = DataBaseUtil.getDatabase();


Para Kotlin Pruebe esto:

class DatabaseUtil { companion object { private val firebaseDatabase: FirebaseDatabase = FirebaseDatabase.getInstance() init { firebaseDatabase.setPersistenceEnabled(true) } fun getDatabase() : FirebaseDatabase { return firebaseDatabase } } }


Para mí, es más fácil manejarlo creando una clase separada para Firebase. Esto se debe a que Firebase tiene su propia instancia y si la está utilizando en más de una actividad, existe la posibilidad de que se cuelgue si vuelve a llamar a setPersistenceEnabled en otra actividad.

Otra cosa buena es que puedes pasar tu contexto o tus parámetros al constructor de FirebaseHandler si es necesario. O si ha fijado la ubicación en la base de datos, se puede llamar fácil sin la repetición .child ("location").

Ejemplo:

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

Esto se puede llamar en cualquier actividad como a continuación.

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


Puedes usar:

FirebaseDatabase.getInstance().setPersistenceEnabled(true);

antes de usar FirebaseDatabase.getInstance().getReference();


Si no te gustan los campos estáticos, este me fue el truco:

if (FirebaseApp.getApps(context).isEmpty()) { FirebaseApp.initializeApp(context); FirebaseDatabase.getInstance().setPersistenceEnabled(true); }

Esto puede deberse a que más de un proceso inicializó dos veces las aplicaciones Firebase o Multidex. Para obtener más información, consulte esto: github.com/firebase/quickstart-android/issues/15


Simplemente mueva su código en ExampleFragment.class desde el método onCreateView al método onCreate:

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FirebaseDatabase.getInstance().setPersistenceEnabled(true); } @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { .... // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_home, container, false);


Solucioné esta excepción usando setPersistenceEnabled(true) en mi clase de Application .

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

En AndroidManifest.xml, establezca el nombre de la aplicación como MApplication:

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


También estoy enfrentando algún problema, pero esta es mi solución temporal para mi aplicación.

Create BaseActivity extends AppcompatActivity y anula onCreate, pon setPersistenceEnabled allí.

public class BaseActivity extends AppCompatActivity { private static String TAG = "BaseActivity"; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); try{ FirebaseDatabase.getInstance().setPersistenceEnabled(true); Log.d(TAG,FirebaseDatabase.getInstance().toString()); }catch (Exception e){ Log.w(TAG,"SetPresistenceEnabled:Fail"+FirebaseDatabase.getInstance().toString()); e.printStackTrace(); } } }

Y cambie MainActivity para extender BaseActivity

public class MainActivity extends BaseActivity

EDITAR: Sigue la respuesta de @imakeApps

public class BaseActivity extends AppCompatActivity { private static String TAG = "BaseActivity"; static boolean isInitialized = false; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); try{ if(!isInitialized){ FirebaseDatabase.getInstance().setPersistenceEnabled(true); isInitialized = true; }else { Log.d(TAG,"Already Initialized"); } }catch (Exception e){ e.printStackTrace(); } } }


Un ContentProvider inicializa una FirebaseApp para que no se inicialice en el momento en que se llama a onCreate() .

Obtenga su FirebaseDatabase así:

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

A continuación, llame a Utils.getDatabase() desde cualquier actividad para usar la base de datos.

No te olvides de compile ''com.google.firebase:firebase-database:...'' en build.gradle

Leer más en este artículo


En Menifest

android:name=".AppName

Crear una clase Java que extienda la aplicación

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