【问题标题】:Firestore database keeps crashingFirestore 数据库不断崩溃
【发布时间】:2018-04-13 20:47:46
【问题描述】:

我已成功将我的应用程序从 RealtimeDB 迁移到 Firestore,但在迁移应用程序后经常崩溃并出现以下错误,如何解决此问题?我在使用 RealtimeDB 时从未遇到过这个错误

Fatal Exception: java.lang.RuntimeException: Internal error in Firestore (0.6.6-dev).

   at com.google.android.gms.internal.zzejs.run(Unknown Source)
   at android.os.Handler.handleCallback(Handler.java:751)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6184)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:788)`

Caused by java.lang.RuntimeException: Failed to gain exclusive lock to the Firestore client's offline persistence. 
This generally means you are using Firestore from multiple processes in your app. 
Keep in mind that multi-process Android apps execute the code in your Application class in all processes, 
so you may need to avoid initializing Firestore in your Application class. 
If you are intentionally using Firestore from multiple processes, 
you can only enable offline persistence (i.e. call setPersistenceEnabled(true)) in one of them.

  `at com.google.android.gms.internal.zzefi.start(Unknown Source)
   at com.google.android.gms.internal.zzeca.zza(Unknown Source)
   at com.google.android.gms.internal.zzecc.run(Unknown Source)
   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
   at java.util.concurrent.FutureTask.run(FutureTask.java:237)
   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
   at com.google.android.gms.internal.zzejp$zza.run(Unknown Source)
   at java.lang.Thread.run(Thread.java:761)`

【问题讨论】:

  • 您是否多次打开与 Firestore 的连接?请指定您使用的 SDK 和版本。我猜这是一个 Android Java SDK,对吧?
  • 我遇到了完全相同的错误。我已经用 RxJava2 的 Single 包装了 Firestore 插入代码,并且在订阅它时我指定了 subscribeOn(Schedulers.io)。这就是问题所在,因为 Schedulers.io 正在启动不同的线程

标签: firebase firebase-realtime-database google-cloud-firestore


【解决方案1】:

如果您尝试从多个线程访问数据库,则会出现此问题。因此,如果您使用的是 RX,则需要为所有插入创建一个后台线程。这是因为 Firestore 在写入时锁定了数据库。

val FIRESTORE_OPERATION_THREAD = Schedulers.single()
yourSingle.subscribeOn(FIRESTORE_OPERATION_THREAD)
. ...

【讨论】:

  • 数据库是从多个线程访问的,我没有使用 RX。所以这个解决方案对我不起作用
  • 没有问题,然后使用执行器。 val myExecutor = Executors.newSingleThreadExecutor() myExecutor.execute(yourRunnable) 在使用它之前,请阅读它的文档一次。
【解决方案2】:

@Sandip Soni 会在各种调用不相互交错(如重复插入)时起作用,并且由于 Firebase 的异步性质,它们可能会这样做。对我有用的是一个小技巧,同步对Firestore 实例的访问并在任何外部线程之外触发一个写操作,以便让Firestore 在它自己的线程中获取本地数据库实例。写操作是任意的,只是为了设置目的:

class Firestore {
    companion object {
       val instance: FirebaseFirestore by lazy {
           return@lazy synchronized(Firestore::class){
               FirebaseFirestore.getInstance().apply { lock() }
           }
       }

       private fun FirebaseFirestore.lock() {
          collection("config").document("db").update("locked", true)
       }
    }
}

【讨论】:

    【解决方案3】:

    您必须在应用中的多个进程中使用 Firestore。多进程 Android 应用在所有进程中执行您的 Application 类中的代码。

    要解决该错误,您可能需要:

    1. 避免在应用程序类或 Rxjava 模块中初始化 Firestore。相反,在每次调用 firestore 数据库之前初始化一个新的 Firestore 实例,如下所示:

      val fireStore = FirebaseFirestore.getInstance()
      val settings = FirebaseFirestoreSettings.Builder()
              //offline persistence is enabled automatically in Android
              .setTimestampsInSnapshotsEnabled(true)
              .build()
      fireStore.firestoreSettings = settings
      //go ahead and call database using the Firestore instance
      

      这意味着您不会将同一个 Firestore 实例用于多个调用。

    2. 然后清除您的应用程序缓存

    【讨论】:

    【解决方案4】:

    只需清除设置中的Application's cache。这对我有用!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-21
      • 1970-01-01
      • 2018-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-03
      相关资源
      最近更新 更多