We used Firebase Database to synchronize data and we found an exception in crash report. Here is brief log:
Caused by com.google.firebase.database.DatabaseException:
Failed to gain exclusive lock to Firebase Database's offline persistence.
...
Caused by android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5): ,
while compiling: PRAGMA journal_mode
More detail log is here. Here is our Firebase Database init code
// run in Application onCreate method
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
Mostly, HTC mobiles with API level 19 are impact. We try to reproduce this
bug, but fail.
Related
I have an DB migration:
val MIGRATION_8_9 = object : Migration(8, 9) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE RideEntity RENAME frontVideoPresent TO frontVideoState")
database.execSQL("ALTER TABLE RideEntity RENAME rearVideoPresent TO rearVideoState")
}
}
When testing this migration on local Samsung phones it worked fine. The in production with help of craslytics I seen this crash:
Fatal Exception: java.lang.RuntimeException
Exception while computing database live data.
Caused by android.database.sqlite.SQLiteException
near "frontVideoPresent": syntax error (Sqlite code 1 SQLITE_ERROR): , while
compiling: ALTER TABLE RideEntity RENAME frontVideoPresent TO frontVideoState, (OS
error - 11:Try again)
This is happened on Huawei Mate 20 phone. How to understand better this crash? This is OS related?
I can not remove the rename now, because many users that updated the app the column renaming worked, but users with Huawei phones may suffer this crash.
I am open to your suggestions...
Looks like version of sqlite on some devices doesn't support column renaming because android app use build-in version on sqlite library to android OS. That's why version of sqlite depends on android's api level version (where app running). According to sqlite release notes (paragraph 2) the support for renaming columns was added in version 3.25.0 and according to google docs (and other answer on stackoverflow)the column's renaming on android supports since android api level 30.
To solve the problem of fragmentation of slqlite library you can use android-requery which allows to use last version of sqlile in all android versions(since API level 14). It's easy to use this library with room.
Hello I am using this library since long but without sqlcipher now I have converted my database into sqlcipher and followed all steps which are defined here https://github.com/amitshekhariitbhu/Android-Debug-Database , after application launch when ever I open IP for its showing shared prefences data correctly but when I click on my sqlcipher database it shows nothing and getting log also
In Build.gradle
debug {
resValue("string", "DB_PASSWORD_Obee_MVP", *****")
libraries implemented
debugImplementation 'com.amitshekhar.android:debug-db-encrypt:1.0.6'
When i click on my database I am getting this in logs too
2021-04-22 13:24:05.712 7274-7372/com.xxx.xxxE/ClientServer: Exception.
net.sqlcipher.database.SQLiteException: file is not a database: , while compiling: select count(*) from sqlite_master;
at net.sqlcipher.database.SQLiteCompiledSql.native_compile(Native Method)
at net.sqlcipher.database.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:89)
at net.sqlcipher.database.SQLiteCompiledSql.(SQLiteCompiledSql.java:62)
at net.sqlcipher.database.SQLiteProgram.(SQLiteProgram.java:91)
at net.sqlcipher.database.SQLiteQuery.(SQLiteQuery.java:48)
at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:60)
at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:2016)
at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1902)
at net.sqlcipher.database.SQLiteDatabase.keyDatabase(SQLiteDatabase.java:2669)
at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2599)
at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1247)
at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1214)
at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1186)
at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1135)
at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1336)
at com.amitshekhar.debug.encrypt.sqlite.DebugDBEncryptFactory.create(DebugDBEncryptFactory.java:15)
at com.amitshekhar.server.RequestHandler.openDatabase(RequestHandler.java:187)
at com.amitshekhar.server.RequestHandler.getTableListResponse(RequestHandler.java:306)
at com.amitshekhar.server.RequestHandler.handle(RequestHandler.java:113)
at com.amitshekhar.server.ClientServer.run(ClientServer.java:77)
at java.lang.Thread.run(Thread.java:923)
Below is the details of the exception that is according to different Android devices and unable to find any soliton for it.
I get these details from Firebase Crashlytics as I am unable to reproduce it and is the most frequently according to crash in my Firebase Crashlytics list
Fatal Exception: android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 778)
Error Code : 778 (SQLITE_IOERR_WRITE)
Caused By : Disk I/O error occurred during 'write' operation.
(disk I/O error (code 778))
#
at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(SQLiteConnection.java)
at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:816)
at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:2067)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1996)
at co.uk.rushorm.android.AndroidRushStatementRunner.runRaw(AndroidRushStatementRunner.java:37)
at co.uk.rushorm.core.RushCore$12.statementCreated(RushCore.java:473)
at co.uk.rushorm.core.implementation.ReflectionTableStatementGenerator.generateStatements(ReflectionTableStatementGenerator.java:46)
at co.uk.rushorm.core.RushCore.createTables(RushCore.java:469)
at co.uk.rushorm.core.RushCore.access$200(RushCore.java:39)
at co.uk.rushorm.core.RushCore$13.createClasses(RushCore.java:495)
at co.uk.rushorm.core.implementation.ReflectionUpgradeManager.upgrade(ReflectionUpgradeManager.java:119)
at co.uk.rushorm.core.RushCore.upgrade(RushCore.java:480)
at co.uk.rushorm.core.RushCore.access$300(RushCore.java:39)
at co.uk.rushorm.core.RushCore$1.run(RushCore.java:132)
at java.lang.Thread.run(Thread.java:762)
After we upgraded Google Play Services to:
compile 'com.google.android.gms:play-services-base:7.5.0'
compile 'com.google.android.gms:play-services-analytics:7.5.0'
Note that docs say we have to use play-services-analytics:7.3.0,
however since we are using play services 7.5, we have used the configurations stated at the start.
The app compiles fine but we've noticed our Google Analytics no longer send to our server. And also whenever we make call Tracker.send() the following lines will appear in the error log per event:
06-30 10:51:43.188 13623-13752/com.fairfax.domain E/SQLiteLog﹕ (1032) statement aborts at 31: [INSERT OR REPLACE INTO properties(cid,app_uid,hits_count,adid,params,tid) VALUES (?,?,?,?,?,?)]
06-30 10:51:43.198 13623-13752/com.fairfax.domain E/GAv4﹕ Error storing a property: android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 1032)
06-30 10:51:44.348 13623-13752/com.fairfax.domain E/SQLiteLog﹕ (1032) statement aborts at 31: [INSERT OR REPLACE INTO properties(cid,app_uid,hits_count,adid,params,tid) VALUES (?,?,?,?,?,?)]
06-30 10:51:44.358 13623-13752/com.fairfax.domain E/GAv4﹕ Error storing a property: android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 1032)
06-3
We proxied the traffic and saw that indeed it did not seem to send the GA events.
As a workaround for now we made the change to manual dispatching:
analytics.setLocalDispatchPeriod(0);
and manually calling:
GoogleAnalytics.getInstance(appContext).dispatchLocalHits();
But of course this is less than ideal, how would we let Google Analytics Handle storing/sending based on configurations and not get the errors?
UPD: It is probably worth mentioning that we're upgrading from play services 6.5.
UPD2: We proxied network again and now it appears that GA does send /batch request after a while. Those SQLite errors are still present though:
8273-8329/com.fairfax.domain E/SQLiteLog﹕ (1032) statement aborts at 29: [INSERT OR REPLACE INTO properties(cid,app_uid,hits_count,adid,params,tid) VALUES (?,?,?,?,?,?)]
Is SQLiteLog a class you wrote or Google Analytics provides? If you're using a DBHelper you could try getWritableDatabase() on it.
Do you have any long running services that might be using the old database, or have some lock in it?
You could also try bumping your build number on the app, and looking into a SQL migration.
I'm using this method to copy a pre-existing sqlite-database from my assets-directory to the app's /databases/-directory on the first app launch. This works fine on emulators with different SDK-levels and on my 4.4 devices, but fails on a 2.2.2 device with the following logcat message:
sqlite returned: error code = 11, msg = database corruption found by source line 40107
and further on SELECT locale FROM android_metadata failed
There are other SO-questions with this error, but my database definitely contains an android_metadata-table with a locale column and an en_US entry (which is why the app works on many other emulators and higher-SDK devices) and isn't large (32KB), which I read can be an issue.
Update: I switched to using the SQLiteAssetHelper-library, but am still getting the same error:
copying database from assets...
database copy complete
sqlite returned: error code = 11, msg = database corruption found by source line 40107
sqlite returned: error code = 11, msg = database disk image is malformed
CREATE TABLE android_metadata failed
Failed to setLocale() when constructing, closing the database
It seems the SQLiteOpenHelper (not the AssetHelper) is trying to create the android_metadata table (even though it's already present) and fails because of this?
Update 2: The full stacktrace can be found here
and add a new android_metadata-table with a locale-column and an en_us-row
Now that you are using SQLiteAssetHelper, and given the error message (CREATE TABLE android_metadata failed), remove your manual android_metadata table from your packaged copy of the database. This will be created for you as part of unpacking the database via SQLiteAssetHelper.