firebase / firebase/firebase-unity-sdk
[Bug] Using Firestore's offline persistence on certain Android devices causes the app to force close.
- Dominant language
- C#
- Stars
- 320
- Forks
- 60
- Avg merge
- 11h 15m
- Merged PRs (30d)
- 11
Description
### [REQUIRED] Please fill in the following fields:
* Unity editor version: 2022.3.20f1
* Firebase Unity SDK version: 11.6.0
* Source you installed the SDK: Unity Package Manager
* Problematic Firebase Component: Firestore
* Other Firebase Components in use: None
* Additional SDKs you are using: None
* Platform you are using the Unity editor on: Mac
* Platform you are targeting: Android
* Scripting Runtime: IL2CPP
### [REQUIRED] Please describe the issue here:
```
* Tinno - FIH Foxconn
* M10
* Innovatech - Unisoc
* T30
* Worldchip - Windriver
* P25_T_ROW
* P25_T_EEA
* P80T_ROW
* Deejoy - FIH Foxconn
* Kids_10
* PlimPad_P3_Pro
```
On the above Android device, calling `FirebaseFirestore.Collection`, then closing the app, then starting the app again and calling `FirebaseFirestore.Collection`, the following error occurs and the app is forced to close.
```
FATAL EXCEPTION: main
Process: com.XXXX.YYYY, PID: 9713
java.lang.RuntimeException: Internal error in Cloud Firestore (24.8.1).
at com.google.firebase.firestore.util.AsyncQueue.lambda$panic$3(AsyncQueue.java:545)
at com.google.firebase.firestore.util.AsyncQueue$$ExternalSyntheticLambda3.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7876)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1182)
Caused by: java.lang.RuntimeException: android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5 SQLITE_BUSY)
at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor.lambda$executeAndReportResult$1(AsyncQueue.java:333)
at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$$ExternalSyntheticLambda0.run(Unknown Source:4)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:487)
at java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$DelayedStartFactory.run(AsyncQueue.java:235)
at java.lang.Thread.run(Thread.java:1012)
Caused by: android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5 SQLITE_BUSY)
at android.database.sqlite.SQLiteConnection.nativeExecute(Native Method)
at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:709)
at android.database.sqlite.SQLiteSession.beginTransactionUnchecked(SQLiteSession.java:325)
at android.database.sqlite.SQLiteSession.beginTransaction(SQLiteSession.java:300)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:624)
at android.database.sqlite.SQLiteDatabase.beginTransactionWithListener(SQLiteDatabase.java:587)
at com.google.firebase.firestore.local.SQLitePersistence.runTransaction(SQLitePersistence.java:211)
at com.google.firebase.firestore.local.SQLiteOverlayMigrationManager.buildOverlays(SQLiteOverlayMigrationManager.java:46)
at com.google.firebase.firestore.local.SQLiteOverlayMigrationManager.run(SQLiteOverlayMigrationManager.java:42)
at com.google.firebase.firestore.local.LocalStore.start(LocalStore.java:182)
at com.google.firebase.firestore.core.ComponentProvider.initialize(ComponentProvider.java:156)
at com.google.firebase.firestore.core.FirestoreClient.initialize(FirestoreClient.java:296)
at com.google.firebase.firestore.core.FirestoreClient.lambda$new$0$com-google-firebase-firestore-core-FirestoreClient(FirestoreClient.java:114)
at com.google.firebase.firestore.core.FirestoreClient$$ExternalSyntheticLambda1.run(Unknown Source:8)
at com.google.firebase.firestore.util.AsyncQueue.lambda$enqueue$2(AsyncQueue.java:444)
at com.google.firebase.firestore.util.AsyncQueue$$ExternalSyntheticLambda6.call(Unknown Source:2)
at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor.lambda$executeAndReportResult$1(AsyncQueue.java:330)
... 8 more
```
Firestore offline data persistence behavior not available on the aforementioned Android devices.
#### Steps to reproduce:
1. Add a Firebase project to be able to use "Cloud Firestore".
2. Create a new Unity project, set "Package Name" and add "google-services.json".
3. Add the following Firebase SDKs from the Unity Package Manager.
* com.google.external-dependency-manager-1.2.177.tgz
* com.google.firebase.app-11.6.0.tgz
* com.google.firebase.firestore-11.6.0.tgz
4. Add the following script to your Unity project and attach it to the game objects in your scene.
```cs
using System.Threading.Tasks;
using Firebase;
using Firebase.Firestore;
using UnityEngine;
internal sealed class Example : MonoBehaviour
{
private async Task Start()
{
await FirebaseApp.CheckAndFixDependenciesAsync();
var firebaseFirestore = FirebaseFirestore.DefaultInstance;
firebaseFirestore.Collection( "hoge" );
}
}
```
1. Build the application to the aforementioned Android device.
2. When the call to `firebaseFirestore.Collection` is complete, exit the application.
3. Start the app and wait for the `firebaseFirestore.Collection` call to complete.
4. An error occurs and the application is forcefully terminated (100%).
#### Supplement
* Forced termination does not occur on any device other than the aforementioned Android devices.
* If `PersistenceEnabled` is set to `false` as follows, no forced termination occurs.
```cs
using System.Threading.Tasks;
using Firebase;
using Firebase.Firestore;
using UnityEngine;
internal sealed class Example : MonoBehaviour
{
private async Task Start()
{
await FirebaseApp.CheckAndFixDependenciesAsync();
var firebaseFirestore = FirebaseFirestore.DefaultInstance;
firebaseFirestore.Settings.PersistenceEnabled = false;
firebaseFirestore.Collection( "hoge" );
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.