stefan-niedermann / nextcloud-deck

📋 Android client for nextcloud deck app
https://play.google.com/store/apps/details?id=it.niedermann.nextcloud.deck.play
GNU General Public License v3.0
482 stars 52 forks source link

`SQLiteConstraintException: UNIQUE constraint failed` #1447

Open duckimann opened 1 year ago

duckimann commented 1 year ago

Steps to reproduce the behavior:

  1. Click Choose Account
  2. Choose suitable account
  3. Accept Nextcloud Deck access Nextcloud Account
  4. Wait to import boards
  5. Error shows up

Expected behavior Import available boards

Screenshots Screenshot_2023-03-13-06-53-31-907_it niedermann nextcloud deck Screenshot_2023-03-13-06-52-52-344_it niedermann nextcloud deck

Versions

Smartphone (please complete the following information):

Stacktrace

App Version: 1.21.8
App Version Code: 1021008
Server App Version: 1.8.3
App Flavor: fdroid

Files App Version Code: 30240190

---

OS Version: 4.19.157-perf-g85e27949fb09(V13.0.7.0.SGCMIXM)
OS API Level: 31
Device: spes
Manufacturer: Xiaomi
Model (and Product): 2201117TG (spes_global)

---

android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: Card.accountId, Card.id (code 2067 SQLITE_CONSTRAINT_UNIQUE)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:940)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:89)
    at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.kt:42)
    at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.kt:102)
    at it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.CardDao_Impl.insert(CardDao_Impl.java:263)
    at it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.CardDao_Impl.insert(CardDao_Impl.java:43)
    at it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DataBaseAdapter.createCardDirectly(DataBaseAdapter.java:709)
    at it.niedermann.nextcloud.deck.persistence.sync.helpers.providers.CardDataProvider.createInDB(CardDataProvider.java:84)
    at it.niedermann.nextcloud.deck.persistence.sync.helpers.providers.CardDataProvider.createInDB(CardDataProvider.java:34)
    at it.niedermann.nextcloud.deck.persistence.sync.helpers.SyncHelper$1.onResponse(SyncHelper.java:62)
    at it.niedermann.nextcloud.deck.persistence.sync.helpers.SyncHelper$1.onResponse(SyncHelper.java:47)
    at it.niedermann.nextcloud.deck.persistence.sync.helpers.providers.CardDataProvider$1.onResponse(CardDataProvider.java:63)
    at it.niedermann.nextcloud.deck.persistence.sync.helpers.providers.CardDataProvider$1.onResponse(CardDataProvider.java:58)
    at it.niedermann.nextcloud.deck.api.RequestHelper$ResponseConsumer.accept(RequestHelper.java:52)
    at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:63)
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
    at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:62)
    at io.reactivex.internal.operators.observable.ObservableFromPublisher$PublisherSubscriber.onNext(ObservableFromPublisher.java:56)
    at com.nextcloud.android.sso.api.NextcloudAPI.lambda$performRequestObservableV2$1$com-nextcloud-android-sso-api-NextcloudAPI(NextcloudAPI.java:130)
    at com.nextcloud.android.sso.api.NextcloudAPI$$ExternalSyntheticLambda0.subscribe(Unknown Source:6)
    at io.reactivex.internal.operators.observable.ObservableFromPublisher.subscribeActual(ObservableFromPublisher.java:31)
    at io.reactivex.Observable.subscribe(Observable.java:12284)
    at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:32)
    at io.reactivex.Observable.subscribe(Observable.java:12284)
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
    at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
    at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
    at java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
    at java.lang.Thread.run(Thread.java:1012)
Gobytego commented 1 year ago

i get this exact issue... even tried multiple versions including the play store and f-droid versions. also tried multiple phones/tablets

stefan-niedermann commented 1 year ago

Versions prior to 1.22.x had a known issue in parallel execution that could lead to this error.

Please wait until 1.22.x is available on your store, then clear the storage of the deck android app as described in our FAQ and import your account again.

Gobytego commented 1 year ago

Cannot pinpoint it to just one board. Here is what I did. Made a test user. Kept him out of any groups that are shared with the boards. Shared one board. Worked. Shared each board without clearing data on the app. Worked. Left all boards shared to that user. Cleared the app data. Tried the initial sync. Failed. Tried just one board at a time clearing the app and share on the boards to make sure he is only getting the one board. Worked on all boards. So I can't pinpoint it to one board and I can sort of get it working if I do the first board sync then add one board at a time to that user and refresh sync.

One suggestion if possible is have the user be able to select only the boards they want synced on mobile. It is a suggestion a few of my users want and it might be a quick bandaid for this issue right now.

Gobytego commented 1 year ago

Oh I forgot to say this is all on 1.22.1

Gobytego commented 1 year ago
App Version: 1.22.1
App Version Code: 1022001
Server App Version: 1.8.3
App Flavor: play

Files App Version Code: 30240290

---

OS Version: 4.14.186-gd5b54dace-dirty(root.20220812.180105)
OS API Level: 30
Device: Titan_Slim
Manufacturer: Unihertz
Model (and Product): Titan Slim (Titan_Slim)

---

android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:938)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
    at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.kt:42)
    at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.kt:102)
    at it.niedermann.nextcloud.deck.database.dao.MentionDao_Impl.insert(MentionDao_Impl.java:142)
    at it.niedermann.nextcloud.deck.database.dao.MentionDao_Impl.insert(MentionDao_Impl.java:23)
    at it.niedermann.nextcloud.deck.database.DataBaseAdapter.createMention(DataBaseAdapter.java:1179)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.DeckCommentsDataProvider.persistMentions(DeckCommentsDataProvider.java:90)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.DeckCommentsDataProvider.createInDB(DeckCommentsDataProvider.java:82)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.DeckCommentsDataProvider.createInDB(DeckCommentsDataProvider.java:21)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:62)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:47)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.DeckCommentsDataProvider$1.onResponse(DeckCommentsDataProvider.java:41)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.DeckCommentsDataProvider$1.onResponse(DeckCommentsDataProvider.java:32)
    at it.niedermann.nextcloud.deck.remote.api.RequestHelper$ResponseConsumer.accept(RequestHelper.java:52)
    at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:63)
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
    at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:62)
    at io.reactivex.internal.operators.observable.ObservableFromPublisher$PublisherSubscriber.onNext(ObservableFromPublisher.java:56)
    at com.nextcloud.android.sso.api.NextcloudAPI.lambda$performRequestObservableV2$1$com-nextcloud-android-sso-api-NextcloudAPI(NextcloudAPI.java:130)
    at com.nextcloud.android.sso.api.NextcloudAPI$$ExternalSyntheticLambda0.subscribe(Unknown Source:6)
    at io.reactivex.internal.operators.observable.ObservableFromPublisher.subscribeActual(ObservableFromPublisher.java:31)
    at io.reactivex.Observable.subscribe(Observable.java:12284)
    at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:32)
    at io.reactivex.Observable.subscribe(Observable.java:12284)
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
    at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
    at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:923)
Gobytego commented 1 year ago

This is from the server took out my ip address.

{"reqId":"H2JnTDJzMJHi0QcsD2VV","level":3,"time":"2023-04-07T22:05:24+00:00","remoteAddr":"X.x.x.x","user":"--","app":"index","method":"GET","url":"/index.php/apps/deck/api/v1.1/boards/10/stacks/42/cards/154?","message":"userId must be provided and must be not empty","userAgent":"Mozilla/5.0 (Android) Nextcloud-android/3.24.2","version":"25.0.4.1","exception":{"Exception":"OCA\Deck\BadRequestException","Message":"userId must be provided and must be not empty","Code":0,"Trace":[{"file":"/var/snap/nextcloud/33908/nextcloud/extra-apps/deck/lib/Validators/BaseValidator.php","line":85,"function":"validate","class":"OCA\Deck\Validators\BaseValidator","type":"->"},{"file":"/var/snap/nextcloud/33908/nextcloud/extra-apps/deck/lib/Service/AssignmentService.php","line":108,"function":"check","class":"OCA\Deck\Validators\BaseValidator","type":"->"},{"function":"__construct","class":"OCA\Deck\Service\AssignmentService","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php","line":108,"function":"newInstanceArgs","class":"ReflectionClass","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php","line":116,"function":"buildClass","class":"OC\AppFramework\Utility\SimpleContainer","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php","line":133,"function":"resolve","class":"OC\AppFramework\Utility\SimpleContainer","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/DependencyInjection/DIContainer.php","line":465,"function":"query","class":"OC\AppFramework\Utility\SimpleContainer","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/DependencyInjection/DIContainer.php","line":437,"function":"queryNoFallback","class":"OC\AppFramework\DependencyInjection\DIContainer","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php","line":89,"function":"query","class":"OC\AppFramework\DependencyInjection\DIContainer","type":"->"},{"function":"OC\AppFramework\Utility\{closure}","class":"OC\AppFramework\Utility\SimpleContainer","type":"->","args":[" sensitive parameters replaced "]},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php","line":108,"function":"array_map"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php","line":116,"function":"buildClass","class":"OC\AppFramework\Utility\SimpleContainer","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php","line":133,"function":"resolve","class":"OC\AppFramework\Utility\SimpleContainer","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/DependencyInjection/DIContainer.php","line":465,"function":"query","class":"OC\AppFramework\Utility\SimpleContainer","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/DependencyInjection/DIContainer.php","line":437,"function":"queryNoFallback","class":"OC\AppFramework\DependencyInjection\DIContainer","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/AppFramework/App.php","line":159,"function":"query","class":"OC\AppFramework\DependencyInjection\DIContainer","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/lib/private/Route/Router.php","line":298,"function":"main","class":"OC\AppFramework\App","type":"::"},{"file":"/snap/nextcloud/33908/htdocs/lib/base.php","line":1047,"function":"match","class":"OC\Route\Router","type":"->"},{"file":"/snap/nextcloud/33908/htdocs/index.php","line":36,"function":"handleRequest","class":"OC","type":"::"}],"File":"/var/snap/nextcloud/33908/nextcloud/extra-apps/deck/lib/Validators/BaseValidator.php","Line":66,"CustomMessage":"--"},"id":"643093e78c43b"}

Gobytego commented 1 year ago

And here is the formatted.... Should of pasted this instead of raw. Sorry about that.

[index] Error: OCA\Deck\BadRequestException: userId must be provided and must be not empty at <>

  1. /var/snap/nextcloud/33908/nextcloud/extra-apps/deck/lib/Validators/BaseValidator.php line 85 OCA\Deck\Validators\BaseValidator->validate()
  2. /var/snap/nextcloud/33908/nextcloud/extra-apps/deck/lib/Service/AssignmentService.php line 108 OCA\Deck\Validators\BaseValidator->check()
  3. <> OCA\Deck\Service\AssignmentService->__construct()
  4. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php line 108 ReflectionClass->newInstanceArgs()
  5. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php line 116 OC\AppFramework\Utility\SimpleContainer->buildClass()
  6. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php line 133 OC\AppFramework\Utility\SimpleContainer->resolve()
  7. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/DependencyInjection/DIContainer.php line 465 OC\AppFramework\Utility\SimpleContainer->query()
  8. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/DependencyInjection/DIContainer.php line 437 OC\AppFramework\DependencyInjection\DIContainer->queryNoFallback()
  9. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php line 89 OC\AppFramework\DependencyInjection\DIContainer->query()
  10. <> OC\AppFramework\Utility\SimpleContainer->OC\AppFramework\Utility{closure}(" sensitive parameters replaced ")
    1. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php line 108 array_map()
    2. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php line 116 OC\AppFramework\Utility\SimpleContainer->buildClass()
    3. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/Utility/SimpleContainer.php line 133 OC\AppFramework\Utility\SimpleContainer->resolve()
    4. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/DependencyInjection/DIContainer.php line 465 OC\AppFramework\Utility\SimpleContainer->query()
    5. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/DependencyInjection/DIContainer.php line 437 OC\AppFramework\DependencyInjection\DIContainer->queryNoFallback()
    6. /snap/nextcloud/33908/htdocs/lib/private/AppFramework/App.php line 159 OC\AppFramework\DependencyInjection\DIContainer->query()
    7. /snap/nextcloud/33908/htdocs/lib/private/Route/Router.php line 298 OC\AppFramework\App::main()
    8. /snap/nextcloud/33908/htdocs/lib/base.php line 1047 OC\Route\Router->match()
    9. /snap/nextcloud/33908/htdocs/index.php line 36 OC::handleRequest()

GET /index.php/apps/deck/api/v1.1/boards/10/stacks/42/cards/154? from X.X X.X at 2023-04-07T22:05:24+00:00

stefan-niedermann commented 1 year ago

Thanks for the information!

@desperateCoder should be able to track down the root cause 😉

desperateCoder commented 1 year ago

I'll look into it these days, but this weekend is quite packed already. I'll keep you guys updated!

Gobytego commented 1 year ago

Thank you so much. If I find anything I'll post it.

desperateCoder commented 1 year ago

@Gobytego can you please test the following Build and report back if this one works reliably for you:

APK ¯(°_o)/¯

This is a debug build, which will be installed besides your regular Deck app, but it has a "DEV" label on its icon. Nothing will happen to your actual App.

This build has a ton of changes regarding the sync, so it might just work or just die... Depending on the amount of data on your server the sync may take a while, but it should be more stable from what i can tell.

Gobytego commented 1 year ago

I get this.

App Version: 1.22.1
App Version Code: 1022001
Server App Version: 1.8.3
App Flavor: dev

Files App Version Code: 30240290

---

OS Version: 4.14.186-gd5b54dace-dirty(root.20220812.180105)
OS API Level: 30
Device: Titan_Slim
Manufacturer: Unihertz
Model (and Product): Titan Slim (Titan_Slim)

---

com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException: HTTP request failed with HTTP status-code: 500
    at it.niedermann.nextcloud.deck.remote.api.RequestHelper$ResponseConsumer.lambda$onResponse$0$it-niedermann-nextcloud-deck-remote-api-RequestHelper$ResponseConsumer(RequestHelper.java:50)
    at it.niedermann.nextcloud.deck.remote.api.RequestHelper$ResponseConsumer$$ExternalSyntheticLambda0.run(Unknown Source:6)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:923)
Caused by: java.lang.RuntimeException: HTTP StatusCode wasn't 2xx
    ... 7 more
desperateCoder commented 1 year ago

Did it at least survive longer?

Anyways, the cut-off logs are quite crappy, I'll see if I can make it more verbose. I'll check on this and report back as soon as I have a fix.

Gobytego commented 1 year ago

It seems to be the same. I'll try again.

Gobytego commented 1 year ago

Yah same thing.

desperateCoder commented 1 year ago

Ok, so I enhanced the error messages for failed calls like in your case - I should now see where it fails for the client side (you already provided server logs, thanks for that! I still need to make sure this is the issue on our side as well.)

so the following APK should be more verbose regarding the failed request:

APK (ノ ゜Д゜)ノ ︵ ┻━┻

Please uninstall the DEV app if you didn't do so already and install the APK above. It most probably will die at the exact same moment as before, but will hopefully provide a ton of more context to work with.

Gobytego commented 1 year ago

Now its hanging with no errors. I tried wiping data from all three apps and started again but still just hanging but on a different board.

Gobytego commented 1 year ago

Wait I got something.

App Version: 1.22.1
App Version Code: 1022001
Server App Version: 1.8.3
App Flavor: play

Files App Version Code: 30240290

---

OS Version: 4.14.186-gd5b54dace-dirty(root.20220812.180105)
OS API Level: 30
Device: Titan_Slim
Manufacturer: Unihertz
Model (and Product): Titan Slim (Titan_Slim)

---

android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:938)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
    at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.kt:42)
    at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.kt:102)
    at it.niedermann.nextcloud.deck.database.dao.StackDao_Impl.insert(StackDao_Impl.java:177)
    at it.niedermann.nextcloud.deck.database.dao.StackDao_Impl.insert(StackDao_Impl.java:33)
    at it.niedermann.nextcloud.deck.database.DataBaseAdapter.createStack(DataBaseAdapter.java:681)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.StackDataProvider.createInDB(StackDataProvider.java:44)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.StackDataProvider.createInDB(StackDataProvider.java:20)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:62)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:47)
    at it.niedermann.nextcloud.deck.remote.api.RequestHelper$ResponseConsumer.accept(RequestHelper.java:52)
    at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:63)
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
    at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:62)
    at io.reactivex.internal.operators.observable.ObservableFromPublisher$PublisherSubscriber.onNext(ObservableFromPublisher.java:56)
    at com.nextcloud.android.sso.api.NextcloudAPI.lambda$performRequestObservableV2$1$com-nextcloud-android-sso-api-NextcloudAPI(NextcloudAPI.java:130)
    at com.nextcloud.android.sso.api.NextcloudAPI$$ExternalSyntheticLambda0.subscribe(Unknown Source:6)
    at io.reactivex.internal.operators.observable.ObservableFromPublisher.subscribeActual(ObservableFromPublisher.java:31)
    at io.reactivex.Observable.subscribe(Observable.java:12284)
    at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:32)
    at io.reactivex.Observable.subscribe(Observable.java:12284)
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
    at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
    at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:923)
Gobytego commented 1 year ago
App Version: 1.22.1
App Version Code: 1022001
Server App Version: 1.8.3
App Flavor: play

Files App Version Code: 30240290

---

OS Version: 4.14.186-gd5b54dace-dirty(root.20220812.180105)
OS API Level: 30
Device: Titan_Slim
Manufacturer: Unihertz
Model (and Product): Titan Slim (Titan_Slim)

---

android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:938)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
    at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.kt:42)
    at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.kt:102)
    at it.niedermann.nextcloud.deck.database.dao.UserDao_Impl.insert(UserDao_Impl.java:177)
    at it.niedermann.nextcloud.deck.database.dao.UserDao_Impl.insert(UserDao_Impl.java:29)
    at it.niedermann.nextcloud.deck.database.DataBaseAdapter.createUser(DataBaseAdapter.java:393)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.CardDataProvider.fixRelations(CardDataProvider.java:100)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.CardDataProvider.createInDB(CardDataProvider.java:83)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.CardDataProvider.createInDB(CardDataProvider.java:34)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:62)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:47)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.CardDataProvider$1.onResponse(CardDataProvider.java:63)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.CardDataProvider$1.onResponse(CardDataProvider.java:58)
    at it.niedermann.nextcloud.deck.remote.api.RequestHelper$ResponseConsumer.accept(RequestHelper.java:52)
    at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:63)
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
    at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:62)
    at io.reactivex.internal.operators.observable.ObservableFromPublisher$PublisherSubscriber.onNext(ObservableFromPublisher.java:56)
    at com.nextcloud.android.sso.api.NextcloudAPI.lambda$performRequestObservableV2$1$com-nextcloud-android-sso-api-NextcloudAPI(NextcloudAPI.java:130)
    at com.nextcloud.android.sso.api.NextcloudAPI$$ExternalSyntheticLambda0.subscribe(Unknown Source:6)
    at io.reactivex.internal.operators.observable.ObservableFromPublisher.subscribeActual(ObservableFromPublisher.java:31)
    at io.reactivex.Observable.subscribe(Observable.java:12284)
    at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:32)
    at io.reactivex.Observable.subscribe(Observable.java:12284)
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
    at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
    at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:923)
Gobytego commented 1 year ago

Screenshot_20230409-123217

desperateCoder commented 1 year ago

I'm slightly confused:

App Flavor: play

This is your actual app, not the one I posted above, right? The dev build should be like App Flavor: dev or am I missing something?

Edit:

In case something won't work (e.g. no error at all, but no sync either) please try to delete app data before uninstalling. Android behaves quite randomly when it comes to uninstalling apps ..

Gobytego commented 1 year ago

Oh maybe I accedently hit the regular app. Hold I'll do it again.

Gobytego commented 1 year ago

Screenshot_20230409-142922

So tried it again and it just hangs here with no traffic or anything.

Gobytego commented 1 year ago

Ok so I uninstalled both the nextcloud app. And the deck app plus the deck Dev you sent. Just reinstalled both the nextcloud app and the deck Dev. Its now just sitting there looks like its stuck on importing either board 5,8,9, or 11 but no error. Where as before with the non Dev version it wouldn't get past board 4 with out giving me a bunch of the error.

Gobytego commented 1 year ago

Okay this time it got stuck on 6. Very inconsistent. But still no error.

desperateCoder commented 1 year ago

how long did you let it do its thing? as mentioned, the time it runs highly depends of a boards data. Can you just let it do whatever it does for a longer period of time? I have a quite big test-account with like hundreds of cards and it took like 20 minutes to finally finish... if you have a log viewer (e.g. logcat) installed, you could check out if the app is still logging stuff, i bet it does. I didn't experience a single case of "it just stopped doing stuff", it either dies or just takes its time.

Gobytego commented 1 year ago

Okay I'll keep it going.

Gobytego commented 1 year ago

Here are two screen shots. One from a little after I started and one from now. It seems to just be sitting there but I'll keep it going. Screenshot_20230409-145829

Gobytego commented 1 year ago

Screenshot_20230409-153810

desperateCoder commented 1 year ago

Do you have a board with a lot of cards and comments?

Gobytego commented 1 year ago

Its still going. Screenshot_20230409-193840

Gobytego commented 1 year ago

None of the boards really have too much. Like what would be considered a lot?

Gobytego commented 1 year ago

I am goanna try syncing with our old server. There is about 2000 cards per board on there and see if it gives issues.

desperateCoder commented 1 year ago

None of the boards really have too much. Like what would be considered a lot?

I'd say like 150 cards for a deck? keep in mind that every card can have its comments, attachments and activities, its like a trunk and its roots.... the deeper you go the more ends you'll find.

I am goanna try syncing with our old server. There is about 2000 cards per board on there and see if it gives issues.

I think this isn't a experiment worth trying in the current situation :sweat_smile: As we're struggling with the current amount, I guess this will also fail.

I have a suspicion what could have caused this behavior of doing nothing - its something i introduced in this particular branch, but lets see if it behaves differently if i undo this change:

APK (ಥ﹏ಥ)

As always: make sure to delete app data before re-installing the app.

btw: thanks for your patience and cooperation! thats really helpful!

Gobytego commented 1 year ago

I am goanna try syncing with that one. Give me a few mins

Gobytego commented 1 year ago

Ok with this build I got an error right away.

Full Crash:

App Version: 1.22.1
App Version Code: 1022001
App Flavor: dev

Files App Version Code: 30240290

---

OS Version: 4.14.186-gd5b54dace-dirty(root.20220812.180105)
OS API Level: 30
Device: Titan_Slim
Manufacturer: Unihertz
Model (and Product): Titan Slim (Titan_Slim)

---

java.lang.UnsupportedOperationException: Not implemented
    at com.nextcloud.android.sso.helper.Retrofit2Helper$1.request(Retrofit2Helper.java:99)
    at it.niedermann.nextcloud.deck.remote.api.RequestHelper$ResponseConsumer.buildCause(RequestHelper.java:56)
    at it.niedermann.nextcloud.deck.remote.api.RequestHelper$ResponseConsumer.onResponse(RequestHelper.java:51)
    at com.nextcloud.android.sso.helper.Retrofit2Helper$1.lambda$enqueue$0$com-nextcloud-android-sso-helper-Retrofit2Helper$1(Retrofit2Helper.java:72)
    at com.nextcloud.android.sso.helper.Retrofit2Helper$1$$ExternalSyntheticLambda0.run(Unknown Source:6)
    at java.lang.Thread.run(Thread.java:923)
desperateCoder commented 1 year ago

ok thanks! can you please try the following:

APK (⊙_⊙')

this should hopefully fix the error above.

Gobytego commented 1 year ago

This is what I get.

Full Crash:

App Version: 1.22.1
App Version Code: 1022001
App Flavor: dev

Files App Version Code: 30240290

---

OS Version: 4.14.186-gd5b54dace-dirty(root.20220812.180105)
OS API Level: 30
Device: Titan_Slim
Manufacturer: Unihertz
Model (and Product): Titan Slim (Titan_Slim)

---

android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:938)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
    at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.kt:42)
    at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.kt:102)
    at it.niedermann.nextcloud.deck.database.dao.CommentDao_Impl.insert(CommentDao_Impl.java:221)
    at it.niedermann.nextcloud.deck.database.dao.CommentDao_Impl.insert(CommentDao_Impl.java:31)
    at it.niedermann.nextcloud.deck.database.DataBaseAdapter.createComment(DataBaseAdapter.java:1152)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.DeckCommentsDataProvider.createInDB(DeckCommentsDataProvider.java:81)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.DeckCommentsDataProvider.createInDB(DeckCommentsDataProvider.java:21)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:62)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:47)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.DeckCommentsDataProvider$1.onResponse(DeckCommentsDataProvider.java:41)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.DeckCommentsDataProvider$1.onResponse(DeckCommentsDataProvider.java:32)
    at it.niedermann.nextcloud.deck.remote.api.IResponseCallback.onResponseWithHeaders(IResponseCallback.java:18)
    at it.niedermann.nextcloud.deck.remote.api.RequestHelper$ResponseConsumer.onResponse(RequestHelper.java:49)
    at com.nextcloud.android.sso.helper.Retrofit2Helper$1.lambda$enqueue$0$com-nextcloud-android-sso-helper-Retrofit2Helper$1(Retrofit2Helper.java:72)
    at com.nextcloud.android.sso.helper.Retrofit2Helper$1$$ExternalSyntheticLambda0.run(Unknown Source:6)
    at java.lang.Thread.run(Thread.java:923)
desperateCoder commented 1 year ago

Ok thanks! I'll have a look at this these days, it's 2:45 o clock here, i should get some sleep... I'll keep you updated!

Gobytego commented 1 year ago

Okay thank you

Gobytego commented 1 year ago

Been testing a lot. Is there anyway to not sync timelines? Seems like is I have cards with a lot of timelines and move them to a board that's not shared everything seems to work fine.

Gobytego commented 1 year ago

ok here is a work around that seems to be ok for now.

share 1 board with the user, any board it does not matter i shared my biggest board with over 2000 cards, each card has an average of 20 comments and also averaging about 15-20 attachments of all kinds, pdf's jpeg, md, odf, etc. once that board is shared then one by one share 1 board at a time then in the mobile app pull down to refresh the data and the board will appear.... let that sync then the next then the next. once done with all boards (in my case about 12) everything works fine.

biggest issue i have is users with multiple devices... example a phone and a tablet... in that case you have to do the same thing but have to do it on both the phone and the tablet at the same time.

doesn't matter how many comments or attachments or how big the timeline is. maybe it wont be a bad idea to let the user have the option to choose one board at a time at first sync. or have it only pull one board then have a continue button or something so it doesn't roll over like it is...

Gobytego commented 1 year ago

Been testing a lot. Is there anyway to not sync timelines? Seems like is I have cards with a lot of timelines and move them to a board that's not shared everything seems to work fine.

yeah disregard this... was not the issue.

desperateCoder commented 1 year ago

Hi @Gobytego,

thanks for the update! You actually found a quite interesting aspect of the sync, that i should reconsider... Currently the sync runs like the roots of a tree - first the boards are synced in a parallel manner, then all stacks of all boards and so on. Maybe I can change that behavior to do this board after board by default, so we don't have to bother the user with this. Ultimately this should just work without forcing the user to do a special choreography.

This will take some time though - please be patient, I'll keep you updated! (We're developing this app in our spare time)

stefan-niedermann commented 1 year ago

@Gobytego thanks for all the help and testing! Would you please write me your Play Store order ID (or your GMail account) via mail (info@niedermann.it) so I can at least refund the money you spent for the app so far? When we have solved the remaining issues, I'll send you a free voucher so you can get it for free from the Play Store. Sorry for the inconveniences :slightly_smiling_face:

Gobytego commented 1 year ago

@Gobytego thanks for all the help and testing! Would you please write me your Play Store order ID (or your GMail account) via mail (info@niedermann.it) so I can at least refund the money you spent for the app so far? When we have solved the remaining issues, I'll send you a free voucher so you can get it for free from the Play Store. Sorry for the inconveniences 🙂

I do not ever want a refund. I want to and encourage people to please donate more to this project!!!! And if you want I can test every version on multiple devices for you instead how's that?

desperateCoder commented 1 year ago

OK, so.... I had to make decisions today: work for my actual job or try to make a thankful and helpful user happy.

Long story short: here you go: ヽ(`Д´)⊃━☆゚. * ・ 。゚, APK

This is exactly what i mentioned above: this version imports the boards in a sequential manner. I tried it on my virtual device multiple times and it worked quite stable (i also had some problems with it in the past, but not on an actual device). The code is quite messy for now, but if you can confirm it to make an actual difference, I'd give it some polishing and it could be released in near future (after some more testing, this version has a ton of other changes)

So feel free to test and provide some feedback, hope it works well :crossed_fingers:

Gobytego commented 1 year ago

Will try asap and get back to you.

Gobytego commented 1 year ago

Damn I get an error.

Full Crash:

App Version: 1.22.1
App Version Code: 1022001
App Flavor: dev

Files App Version Code: 30240290

---

OS Version: 4.14.186-gd5b54dace-dirty(root.20220812.180105)
OS API Level: 30
Device: Titan_Slim
Manufacturer: Unihertz
Model (and Product): Titan Slim (Titan_Slim)

---

android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:938)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
    at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.kt:42)
    at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.kt:102)
    at it.niedermann.nextcloud.deck.database.dao.AttachmentDao_Impl.insert(AttachmentDao_Impl.java:277)
    at it.niedermann.nextcloud.deck.database.dao.AttachmentDao_Impl.insert(AttachmentDao_Impl.java:29)
    at it.niedermann.nextcloud.deck.database.DataBaseAdapter.createAttachment(DataBaseAdapter.java:956)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.AttachmentDataProvider.createInDB(AttachmentDataProvider.java:48)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.AttachmentDataProvider.createInDB(AttachmentDataProvider.java:20)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:67)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:52)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.AttachmentDataProvider.getAllFromServer(AttachmentDataProvider.java:37)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.AbstractSyncDataProvider.getAllFromServer(AbstractSyncDataProvider.java:81)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper.doSyncFor(SyncHelper.java:52)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper.doSyncFor(SyncHelper.java:48)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.CardDataProvider.goDeeper(CardDataProvider.java:150)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.CardDataProvider.goDeeper(CardDataProvider.java:34)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:84)
    at it.niedermann.nextcloud.deck.remote.helpers.SyncHelper$1.onResponse(SyncHelper.java:52)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.CardDataProvider$1.onResponse(CardDataProvider.java:63)
    at it.niedermann.nextcloud.deck.remote.helpers.providers.CardDataProvider$1.onResponse(CardDataProvider.java:58)
    at it.niedermann.nextcloud.deck.remote.api.IResponseCallback.onResponseWithHeaders(IResponseCallback.java:18)
    at it.niedermann.nextcloud.deck.remote.api.RequestHelper$ResponseConsumer.onResponse(RequestHelper.java:49)
    at com.nextcloud.android.sso.helper.Retrofit2Helper$1.lambda$enqueue$0$com-nextcloud-android-sso-helper-Retrofit2Helper$1(Retrofit2Helper.java:72)
    at com.nextcloud.android.sso.helper.Retrofit2Helper$1$$ExternalSyntheticLambda0.run(Unknown Source:6)
    at java.lang.Thread.run(Thread.java:923)
desperateCoder commented 1 year ago

Aw damn, ok. You mentioned a huge deck, maybe I'll need to do the stacks (columns of a board) sequential as well. I'll see when I find some time for it, but I guess it will be next week. In the meantime you can give it a few more tries. Seems like there's still some concurrency issues, but that means that they don't always happen...maybe you get lucky at a third try 🤷