Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Firestore] SQLite error: Cannot perform this operation because there is no current transaction #115

Closed
DavidSerr opened this issue Nov 6, 2018 · 16 comments

Comments

@DavidSerr
Copy link

Environment

Android Studio version: 3.2.1
Firebase Component: Firestore
Component version: 17.1.2

Problem

Steps to reproduce:

Almost immediately, when connected to firestore realtime events, we get this:

2018-11-06 11:00:33.924 18673-18673 E/AndroidRuntime: FATAL EXCEPTION: main
    Process:, PID: 18673
    java.lang.RuntimeException: Internal error in Firestore (0.6.6-dev).
        at com.google.firebase.firestore.util.AsyncQueue.lambda$panic$5(com.google.firebase:firebase-firestore@@17.1.2:377)
        at com.google.firebase.firestore.util.AsyncQueue$$Lambda$5.run(Unknown Source:2)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
     Caused by: java.lang.IllegalStateException: Cannot perform this operation because there is no current transaction.
        at android.database.sqlite.SQLiteSession.throwIfNoTransaction(SQLiteSession.java:925)
        at android.database.sqlite.SQLiteSession.endTransaction(SQLiteSession.java:398)
        at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:683)
        at com.google.firebase.firestore.local.SQLitePersistence.runTransaction(com.google.firebase:firebase-firestore@@17.1.2:172)
        at com.google.firebase.firestore.local.LocalStore.applyRemoteEvent(com.google.firebase:firebase-firestore@@17.1.2:273)
        at com.google.firebase.firestore.core.SyncEngine.handleRemoteEvent(com.google.firebase:firebase-firestore@@17.1.2:315)
        at com.google.firebase.firestore.core.FirestoreClient.handleRemoteEvent(com.google.firebase:firebase-firestore@@17.1.2:230)
        at com.google.firebase.firestore.remote.RemoteStore.raiseWatchSnapshot(com.google.firebase:firebase-firestore@@17.1.2:511)
        at com.google.firebase.firestore.remote.RemoteStore.handleWatchChange(com.google.firebase:firebase-firestore@@17.1.2:420)
        at com.google.firebase.firestore.remote.RemoteStore.access$100(com.google.firebase:firebase-firestore@@17.1.2:52)
        at com.google.firebase.firestore.remote.RemoteStore$1.onWatchChange(com.google.firebase:firebase-firestore@@17.1.2:172)
        at com.google.firebase.firestore.remote.WatchStream.onNext(com.google.firebase:firebase-firestore@@17.1.2:109)
        at com.google.firebase.firestore.remote.WatchStream.onNext(com.google.firebase:firebase-firestore@@17.1.2:39)
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.lambda$onNext$1(com.google.firebase:firebase-firestore@@17.1.2:117)
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver$$Lambda$2.run(Unknown Source:4)
        at com.google.firebase.firestore.remote.AbstractStream$CloseGuardedRunner.run(com.google.firebase:firebase-firestore@@17.1.2:67)
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.onNext(com.google.firebase:firebase-firestore@@17.1.2:110)
        at com.google.firebase.firestore.util.FirestoreChannel$1.onMessage(com.google.firebase:firebase-firestore@@17.1.2:107)
        at io.grpc.ForwardingClientCallListener.onMessage(ForwardingClientCallListener.java:33)
        at io.grpc.ForwardingClientCallListener.onMessage(ForwardingClientCallListener.java:33)
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext(ClientCallImpl.java:526)
        at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
        at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at com.google.firebase.firestore.util.AsyncQueue$DelayedStartFactory.run(com.google.firebase:firebase-firestore@@17.1.2:203)
        at java.lang.Thread.run(Thread.java:        

We have been researching about the issue related with the internal error on firestore module related with SQLite but we found nothing (just clear data on the application each time we restart the app). Our first option to tackle the problem was problably have multiple instances of firestore but this was not the case.

We are trying other options, but at the moment to avoid the crash we disable the persistence through the following code:

firestore.firestoreSettings = FirebaseFirestoreSettings.Builder().setPersistenceEnabled(false).build()

Could you help us with the issue?

@wilhuff
Copy link
Contributor

wilhuff commented Nov 16, 2018

Sorry we missed this when it came in.

We qualify every release, running an application against it, verifying that everything works as expected. Errors on startup should be exceptionally rare. There's a few avenues we can take to figure this out.

The first thing to do is enable logging with FirebaseFirestore.setLoggingEnabled(true) and let's see if there's anything interesting in there.

Secondarily, looking at the code here: https://github.com/firebase/firebase-android-sdk/blob/master/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLitePersistence.java#L164 it looks like it's possible that if there were an exception in referenceDelegate.onTransactionStarted() we could fail to create the transaction, but then execute the finally block and an exception from db.endTransaction() would suppress the first exception and we wouldn't see it. If this is what's happening then the exception we're seeing isn't the root cause. If you could set breakpoints on lines 164, 165, and 172 and report which ones you hit we'd be able to check this hypothesis. (Note that runTransaction is used for everything so there may be a few invocations you'll need to skip. The one that's important is the one where the stack looks like the exception above--namely that the parent is LocalStore.applyRemoteEvent).

Finally if nothing else comes up it's worth describing the environment in which you're running this. Android version, device type, etc. It seems doubtful that this will turn up anything obvious given what you're seeing, but who knows?

@pamartineza
Copy link

I'm experiencing same issue -> http://crashes.to/s/1ef7aa3c95d

@wilhuff
Copy link
Contributor

wilhuff commented Nov 19, 2018

@pamartineza While it's helpful to know that others are experiencing the problem, we haven't seen this issue ourselves, so if you're able to reliably reproduce this, performing the steps outlined above would be useful.

@pamartineza
Copy link

@wilhuff we are unable to reproduce the crash in any of our Test devices, we are just seeing it on Crashlytics. I don't know if it can be related but I can only add that this started happening just after migrating to AndroidX and upgrading to Firestore to 17.1.3

@gsoltis
Copy link
Contributor

gsoltis commented Nov 26, 2018

Do either of you see any exceptions earlier in the log? From my reading, it appears that referenceDelegate.onTransactionStarted() should only throw if a previous transaction was improperly closed. Of course it's also possible something else is going on, so we are additionally working to log the initial underlying exception.

@pamartineza
Copy link

I can't reproduce the issue so I can't get logs, but looking at the crash report http://crashes.to/s/1ef7aa3c95d it seems the problem just happened when users upgraded the App, now that most of the user base has migrated to latest version crashes are remitting

@wilhuff wilhuff changed the title [Firestore] Internal error in Firestore (0.6.6-dev) SQLite [Firestore] SQLite error: Cannot perform this operation because there is no current transaction Nov 27, 2018
@DavidSerr
Copy link
Author

Finally we reproduce the error just access some sections in our app and then pressing the recent apps key at the bottom of the device (I attached the image just to be more clear). Also if we press it repeatedly.

ykcpp

I attached again the log, we updated the component to 17.1.3 version to verify if the error was solved but we have the same result on both.

java.lang.RuntimeException: Internal error in Firestore (0.6.6-dev).
        at com.google.firebase.firestore.util.AsyncQueue.lambda$panic$5(com.google.firebase:firebase-firestore@@17.1.3:377)
        at com.google.firebase.firestore.util.AsyncQueue$$Lambda$5.run(Unknown Source:2)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
     Caused by: java.lang.IllegalStateException: Cannot perform this operation because there is no current transaction.
        at android.database.sqlite.SQLiteSession.throwIfNoTransaction(SQLiteSession.java:925)
        at android.database.sqlite.SQLiteSession.endTransaction(SQLiteSession.java:398)
        at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:683)
        at com.google.firebase.firestore.local.SQLitePersistence.runTransaction(com.google.firebase:firebase-firestore@@17.1.3:172)
        at com.google.firebase.firestore.local.LocalStore.applyRemoteEvent(com.google.firebase:firebase-firestore@@17.1.3:273)
        at com.google.firebase.firestore.core.SyncEngine.handleRemoteEvent(com.google.firebase:firebase-firestore@@17.1.3:315)
        at com.google.firebase.firestore.core.FirestoreClient.handleRemoteEvent(com.google.firebase:firebase-firestore@@17.1.3:230)
        at com.google.firebase.firestore.remote.RemoteStore.raiseWatchSnapshot(com.google.firebase:firebase-firestore@@17.1.3:511)
        at com.google.firebase.firestore.remote.RemoteStore.handleWatchChange(com.google.firebase:firebase-firestore@@17.1.3:420)
        at com.google.firebase.firestore.remote.RemoteStore.access$100(com.google.firebase:firebase-firestore@@17.1.3:52)
        at com.google.firebase.firestore.remote.RemoteStore$1.onWatchChange(com.google.firebase:firebase-firestore@@17.1.3:172)
        at com.google.firebase.firestore.remote.WatchStream.onNext(com.google.firebase:firebase-firestore@@17.1.3:109)
        at com.google.firebase.firestore.remote.WatchStream.onNext(com.google.firebase:firebase-firestore@@17.1.3:39)
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.lambda$onNext$1(com.google.firebase:firebase-firestore@@17.1.3:117)
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver$$Lambda$2.run(Unknown Source:4)
        at com.google.firebase.firestore.remote.AbstractStream$CloseGuardedRunner.run(com.google.firebase:firebase-firestore@@17.1.3:67)
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.onNext(com.google.firebase:firebase-firestore@@17.1.3:110)
        at com.google.firebase.firestore.util.FirestoreChannel$1.onMessage(com.google.firebase:firebase-firestore@@17.1.3:107)
        at io.grpc.ForwardingClientCallListener.onMessage(ForwardingClientCallListener.java:33)
        at io.grpc.ForwardingClientCallListener.onMessage(ForwardingClientCallListener.java:33)
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext(ClientCallImpl.java:526)
        at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
        at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at com.google.firebase.firestore.util.AsyncQueue$DelayedStartFactory.run(com.google.firebase:firebase-firestore@@17.1.3:203)
        at java.lang.Thread.run(Thread.java:764)

After this, when we try to open the app again it crash without doing any action.

Device: Samsung SM-A520F
Android version: 8.0.0, API 26

@wilhuff
Copy link
Contributor

wilhuff commented Nov 27, 2018

This is just the stack trace which doesn't really shed any more light on the situation. We'll try the steps you're describing but in the meantime since you're able to reproduce, could you enable logging with FirebaseFirestore.setLoggingEnabled(true) and post any entries you see? If the log contains anything sensitive you can also send it to me personally at [email protected].

@DavidSerr
Copy link
Author

@wilhuff I have already sent you a more detailed log to your email. Thanks

@gsoltis
Copy link
Contributor

gsoltis commented Nov 29, 2018

Can those seeing this confirm:

  • There are not multiple processes within the app accessing Firestore
  • Whether or not the Firestore library was at some point downgraded then upgraded? I.e. Run with 17.1.2, then 17.1.0, then finally 17.1.3?

And lastly, if you have a full log of a repro you can provide, if you haven't already, that would be very helpful. As above, if it contains sensitive info you can email it to either @wilhuf ([email protected]) or myself ([email protected]).

@linusmartensson
Copy link

linusmartensson commented Jan 15, 2019

@gsoltis @wilhuff I provided a few additional logs and a firebase db dump for this issue to @samtstern after hitting this error repeatedly in an app and stumbling upon a stackoverflow post where he was requesting information. Feel free to contact him for those logs.
Running a multidex app with firebase included via a library project if it matters.

In my specific circumstances, the error seems to have gone away following a full day of upgrade pains, including disabling fabric.io/crashlytics and various updates:

-    api 'com.google.firebase:firebase-core:16.0.5'
-    api 'com.google.firebase:firebase-auth:16.0.5'
-    api 'com.google.firebase:firebase-firestore:17.1.2'
+    api 'com.google.firebase:firebase-core:16.0.6'
+    api 'com.google.firebase:firebase-auth:16.1.0'
+    api 'com.google.firebase:firebase-firestore:17.1.5'

-        classpath 'com.android.tools.build:gradle:3.2.1'
-        classpath 'com.google.gms:google-services:4.1.0'
+        classpath 'com.android.tools.build:gradle:3.3.0'
+        classpath 'com.google.gms:google-services:4.2.0'
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip

It's hard for me to specify exactly what caused the crash, but it did return once more after deleting firebase from my app data, before disappearing following the more thorough upgrade above. I can't say yet if it's gone permanently though.

@gsoltis
Copy link
Contributor

gsoltis commented Jan 18, 2019

Does the database backup you supplied demonstrate the issue? Or is it now fixed running the latest version against that database?

My best guess for what is happening is as follows:

  • at some point firestore was upgraded
  • then downgraded
  • then run again at a later version

This scenario resulted in an unexpected schema, and an exception is being thrown by a query. Unfortunately, this exception is masked by our transaction handling code, so we cannot see from this log what is causing it. Newer versions (17.1.4 and forward) have added code to report this exception. Version 17.1.5 and forward are now safe to downgrade to, and then upgrade from. Prior to this version, downgrading and then upgrading could result in exceptions. The exact symptom depends on the exact series of upgrades and downgrades, but in general it is unsafe prior to 17.1.5.

@linusmartensson
Copy link

I can say as much as i know the supplied database exhibited the issue on the previous version, but after the upgrade it seems to be gone. I have never to my knowledge reverted to an earlier version of the database.
I could try downgrading firebase and restore this database to see if the issue returns, and if so, step up my firebase version in a manual bisect to see what happens?

@gsoltis
Copy link
Contributor

gsoltis commented Jan 23, 2019

If it's working on the current version, there's probably no need to do the bisect. I will keep poking at it a bit on my end to see if I can find out what the underlying exception is. But, failing that, the latest version should report the actual exception so that if it surfaces again it should be much easier to identify.

@linusmartensson
Copy link

linusmartensson commented Jan 23, 2019 via email

@gsoltis
Copy link
Contributor

gsoltis commented Jan 29, 2019

I'm going to mark this as closed, as I believe it is fixed in the most recent version. If anyone is still encountering this issue, please reopen.

@gsoltis gsoltis closed this as completed Jan 29, 2019
@firebase firebase locked and limited conversation to collaborators Oct 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants