com.google.firebase.database.DatabaseException:必须在使用 FirebaseDatabase 实例之前调用 setPersistenceEnabled()

Posted

技术标签:

【中文标题】com.google.firebase.database.DatabaseException:必须在使用 FirebaseDatabase 实例之前调用 setPersistenceEnabled()【英文标题】:com.google.firebase.database.DatabaseException: Calls to setPersistenceEnabled() must be made before any other usage of FirebaseDatabase instance 【发布时间】:2016-10-11 18:16:02 【问题描述】:

当我尝试在 fIREBASE 中设置持久性时遇到问题,有人可以解释一下如何去做吗?

protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_meal_details);

        if (mDatabase == null) 
            mDatabase = FirebaseDatabase.getInstance().getReference();
            FirebaseDatabase.getInstance().setPersistenceEnabled(true);
            // ...
        


       // FirebaseDatabase.getInstance().setPersistenceEnabled(true);
        mDatabase = FirebaseDatabase.getInstance().getReference();

【问题讨论】:

除了弗兰克的回答外,您应该添加一个检查,例如savedInstanceState == null,以确保在活动重新启动时不会再次执行该语句。否则,旋转设备时会出现异常。 【参考方案1】:

根据 Firebase 文档,setPersistenceEnabled 只能调用一次(在创建任何其他 FirebaseDatabase 实例之前)

所以对我来说这个问题的解决方案如下

    您需要创建一个,它扩展android.app.ApplicationsetPersistenceEnabled(true)

举例

class MyFirebaseApp extends android.app.Application 

@Override
public void onCreate() 
    super.onCreate();
    /* Enable disk persistence  */
    FirebaseDatabase.getInstance().setPersistenceEnabled(true);

    Manifest 中,将 MyFirebaseApp 类链接到应用程序标记

举例

在您的应用程序标签中添加以下内容

android:name="com.example.MyFirebaseApp"

这应该可以正常工作。

也不要在任何其他 Activity 中使用 setPersistenceEnabled。

【讨论】:

我试过这个,我反复收到以下异常 致命异常:主进程:co.transportsystems.offrie:background_crash,PID:27025 java.lang.RuntimeException:无法创建应用程序 com.android.tools .fd.runtime.BootstrapApplication:java.lang.IllegalStateException:名称为 [DEFAULT] 的 FirebaseApp 不存在。关于为什么会发生这种情况的任何想法? 这对我有用...谢谢 siddhesh.. +1 从我身边。 除此之外,如果您已经将android:name 用于应用程序标签上的另一个应用程序类并且您无法更改它(例如使用 MultiDexApplication 配置具有超过 64K 方法的应用程序,例如我在做)你可以让 MyFirebaseApp 扩展那个类。 这对我有用,似乎是要走的路。谢谢!【参考方案2】:

类似这样的东西(iirc):

 if (mDatabase == null) 
     FirebaseDatabase database = FirebaseDatabase.getInstance();
     database.setPersistenceEnabled(true);
     mDatabase = database.getReference();
     // ...
 

【讨论】:

firebase 团队是否有针对此问题的最佳实践 Frank?我已经看到您对这个问题提供了 2 或 3 个不同的答案。请您指出一个最佳实践吗?【参考方案3】:

创建一个将在整个应用程序中使用的应用程序类,并在其中初始化 firebase Persistence: 该类应扩展 Application。(ClassName 扩展 Application):

这是一个例子:

FirebaseHandler 类

你可以给类命名/命名任何你想要的名字

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

将应用程序类添加到您的Manifest

 <application
    android:name=".FirebaseHandler"
    android:allowBackup="true"
    android:icon="@mipmap/app_icon"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">

这样数据持久性将应用于您的整个项目。 为了将磁盘持久性应用于特定数据。

DatabaseReference myRef=FirebaseDatabase.getInstance().getReference("people"); 
myRef.keepSynced(true);

这将使您的离线数据保持同步和最新

myRef.keepSynced(true);

了解有关磁盘持久性的更多信息 Here

【讨论】:

【参考方案4】:

此解决方案适用于我,无需扩展 android.app.Application

private static FirebaseDatabase firebaseDatabase;

    if (firebaseDatabase == null) 
        firebaseDatabase=FirebaseDatabase.getInstance();
        firebaseDatabase.setPersistenceEnabled(true);
    
    /* Do your other stuff  */

if (savedInstanceState == null) 
   FirebaseDatabase.getInstance().setPersistenceEnabled(true);

【讨论】:

【参考方案5】:

只需将其添加到您的活动类的顶部:

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

为我工作,但不确定这是否是最佳做法。

【讨论】:

由于某种原因再次使用它时发生了崩溃,因此使用风险自负。【参考方案6】:

如果您在应用程序中扩展 ContentProvider,您可以调用 FirebaseDatabase.getInstance().setPersistenceEnabled(true); 在你的ContentProvideronCreate() 方法中,因为这个方法甚至在你的启动器活动的onCreate() 方法之前被调用。当您在应用程序中使用TaskStackBuilder 创建一个合成的活动堆栈以跳过一些活动并继续前进时,这也很有用,就像您在应用程序通知中使用时一样。因此,当您返回到向后移动的启动器活动时,您可能已经在应用程序的某处使用了 FirebaseDatabase 实例,并且在这种情况下也可能会弹出您遇到的错误。

【讨论】:

【参考方案7】:

如果您使用的是 Kotlin,以下代码对我有用。我在类的顶部声明为私有成员变量。

private val firebaseInstance = FirebaseDatabase.getInstance().apply  setPersistenceEnabled(true) 

【讨论】:

【参考方案8】:

这对我有用。将此添加到您的启动活动!

try            
    FirebaseDatabase.getInstance().setPersistenceEnabled(true);
 catch (Exception e) 

【讨论】:

【参考方案9】:

您可以在调用setPersistenceEnabled.之前尝试检查是否有任何已初始化的firebase应用程序

if (FirebaseApp.getApps(this).size() == 0)
    FirebaseDatabase.getInstance().setPersistenceEnabled(true);

【讨论】:

如果有其他应用使用firebase?可以用吗? 最好初始化任何应用程序

以上是关于com.google.firebase.database.DatabaseException:必须在使用 FirebaseDatabase 实例之前调用 setPersistenceEnabled()的主要内容,如果未能解决你的问题,请参考以下文章