Crash when moving card with custom tags between boards
**Describe the bug**
The app crashes when a card with a custom tag is moved between boards.


**To reproduce**
Issue is reproducible with an account from [try.nextcloud.com](https://try.nextcloud.com):
- [ ] Yes
- [ ] No

Sorry I can't test it right now, I'll test it in few days

Steps to reproduce the behavior:
1. Create a new card in a board
2. Add a custom tag and add the tag to the card
3. Create a new board
4. Move the card to the new board


**Expected behavior**
The card is moved with the custom tag still attached to it.


**Screenshots**
N/a


**Versions**
 - Nextcloud: 
 - Nextcloud Deck: 
 - Nextcloud Android: 
 - Nextcloud Android Deck: 1.13.1


**Smartphone (please complete the following information):**
- Device: Xiaomi Poco F1
- Android-Version: 10
- App-Store:
  - [ ] Google Play Store
  - [ ] Google Play Store (Beta channel)
  - [X] F-Droid
  - [ ] Huawei AppGallery


**Are you using LDAP?**
- [ ] Yes
- [X] No


**Stacktrace**
```
Full Crash:

App Version: 1.13.1
App Version Code: 1013001
App Flavor: fdroid

Files App Version Code: 30140190

---

OS Version: 4.9.247-perf-gc4c46f782703-ab4000128c1a(4000128c1a)
OS API Level: 29
Device: beryllium
Manufacturer: Xiaomi
Model (and Product): POCO F1 (beryllium)

---

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:879)
	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.java:51)
	at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.java:114)
	at it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.JoinCardWithLabelDao_Impl.insert(JoinCardWithLabelDao_Impl.java:153)
	at it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.JoinCardWithLabelDao_Impl.insert(JoinCardWithLabelDao_Impl.java:26)
	at it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DataBaseAdapter.createJoinCardWithLabel(DataBaseAdapter.java:327)
	at it.niedermann.nextcloud.deck.persistence.sync.SyncManager.lambda$assignLabelToCard$41$SyncManager(SyncManager.java:1561)
	at it.niedermann.nextcloud.deck.persistence.sync.-$$Lambda$SyncManager$PNTWheRDo7L9Ue2SXZBBIeCZrgA.run(Unknown Source:8)
	at java.lang.Thread.run(Thread.java:919)

```

diff --git a/app/build.gradle b/app/build.gradle
index 23f6a2c19..14dbc327f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -27,7 +27,8 @@ apply plugin: 'org.greenrobot.greendao'
 
 dependencies {
     implementation 'io.reactivex.rxjava2:rxjava:2.1.4'
-    implementation 'com.github.nextcloud:android-SingleSignOn:0.1.2'
+    //implementation 'com.github.nextcloud:android-SingleSignOn:0.1.2'
+    compile project(':Android-SingleSignOn')
     implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
     implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
     implementation 'com.google.code.gson:gson:2.8.5'
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/api/ApiProvider.java b/app/src/main/java/it/niedermann/nextcloud/deck/api/ApiProvider.java
index 564298672..113c9d6ee 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/api/ApiProvider.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/api/ApiProvider.java
@@ -3,10 +3,13 @@ package it.niedermann.nextcloud.deck.api;
 import android.content.Context;
 
 import com.nextcloud.android.sso.api.NextcloudAPI;
+import com.nextcloud.android.sso.api.NextcloudRetrofitServiceMethod;
 import com.nextcloud.android.sso.exceptions.SSOException;
 import com.nextcloud.android.sso.helper.SingleAccountHelper;
 import com.nextcloud.android.sso.model.SingleSignOnAccount;
 
+import retrofit2.NextcloudRetrofitApiBuilder;
+
 /**
  * Created by david on 26.05.17.
  */
@@ -14,43 +17,26 @@ import com.nextcloud.android.sso.model.SingleSignOnAccount;
 public class ApiProvider {
 
     private static final String TAG = ApiProvider.class.getCanonicalName();
+    private static final String API_ENDPOINT = "/index.php/apps/deck/api/v1.0/";
+
     private DeckAPI mApi;
     private Context context;
-    private boolean connected = false;
-    NextcloudAPI nextcloudAPI = null;
-
 
     public ApiProvider(Context context) {
         this.context = context;
     }
 
-    public void initSsoApi(final NextcloudAPI.ApiConnectedListener callback) {
-
+    void initSsoApi(final NextcloudAPI.ApiConnectedListener callback) {
         try {
             SingleSignOnAccount ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(context);
-            nextcloudAPI = new NextcloudAPI(context, ssoAccount, GsonConfig.GetGson(), new NextcloudAPI.ApiConnectedListener() {
-                @Override
-                public void onConnected() {
-                    connected = true;
-                    mApi = new DeckAPI_SSO(nextcloudAPI);
-                    callback.onConnected();
-                }
-
-                @Override
-                public void onError(Exception ex) {
-                    ex.printStackTrace();
-                    callback.onError(ex);
-                }
-            });
+            NextcloudAPI nextcloudAPI = new NextcloudAPI(context, ssoAccount, GsonConfig.GetGson(), callback);
+            //mApi = new DeckAPI_SSO(nextcloudAPI);
+            mApi = new NextcloudRetrofitApiBuilder(nextcloudAPI, API_ENDPOINT).create(DeckAPI.class);
         } catch (SSOException e) {
             callback.onError(e);
         }
     }
 
-    public boolean isConnected() {
-        return connected;
-    }
-
     public DeckAPI getAPI() {
         return mApi;
     }
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/api/DeckAPI.java b/app/src/main/java/it/niedermann/nextcloud/deck/api/DeckAPI.java
index 229d0553c..c5fcaee07 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/api/DeckAPI.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/api/DeckAPI.java
@@ -24,10 +24,10 @@ public interface DeckAPI {
         Observable createBoard(@Body Board board);
 
         @GET("boards/{id}")
-        Observable<Board> getBoard(@Path("id") long id, @Header("If-Modified-Since") Date lastSync);
+        Observable<Board> getBoard(@Path("id") long id, @Header("If-Modified-Since") String lastSync);
 
         @GET("boards")
-        Observable<List<Board>> getBoards(@Header("If-Modified-Since") Date lastSync);
+        Observable<List<Board>> getBoards(@Header("If-Modified-Since") String lastSync);
 
 
         // ### Stacks
@@ -41,13 +41,13 @@ public interface DeckAPI {
         Observable<Stack> deleteStack(@Path("boardId") long boardId, @Path("stackId") long id);
 
         @GET("boards/{boardId}/stacks/{stackId}")
-        Observable<Stack> getStack(@Path("boardId") long boardId, @Path("stackId") long id, @Header("If-Modified-Since") Date lastSync);
+        Observable<Stack> getStack(@Path("boardId") long boardId, @Path("stackId") long id, @Header("If-Modified-Since") String lastSync);
 
         @GET("boards/{boardId}/stacks")
-        Observable<List<Stack>> getStacks(@Path("boardId") long boardId, @Header("If-Modified-Since") Date lastSync);
+        Observable<List<Stack>> getStacks(@Path("boardId") long boardId, @Header("If-Modified-Since") String lastSync);
 
         @GET("boards/{boardId}/stacks/archived")
-        Observable<List<Stack>> getArchivedStacks(@Path("boardId") long boardId, @Header("If-Modified-Since") Date lastSync);
+        Observable<List<Stack>> getArchivedStacks(@Path("boardId") long boardId, @Header("If-Modified-Since") String lastSync);
 
 
         // ### Cards
@@ -61,12 +61,12 @@ public interface DeckAPI {
         Observable<Card> deleteCard(@Path("boardId") long boardId, @Path("stackId") long stackId, @Path("cardId") long cardId);
 
         @GET("boards/{boardId}/stacks/{stackId}/cards/{cardId}")
-        Observable<Card> getCard(@Path("boardId") long boardId, @Path("stackId") long stackId, @Path("cardId") long cardId, @Header("If-Modified-Since") Date lastSync);
+        Observable<Card> getCard(@Path("boardId") long boardId, @Path("stackId") long stackId, @Path("cardId") long cardId, @Header("If-Modified-Since") String lastSync);
 
 
         // ### LABELS
         @GET("boards/{boardId}labels/{labelId}")
-        Observable<Label> getLabel(@Path("boardId") long boardId, @Path("labelId") long labelId, @Header("If-Modified-Since") Date lastSync);
+        Observable<Label> getLabel(@Path("boardId") long boardId, @Path("labelId") long labelId, @Header("If-Modified-Since") String lastSync);
 
         @PUT("boards/getBoards/{boardId}/labels/{labelId}")
         Observable<Label> updateLabel(@Path("boardId") long boardId, @Path("labelId") long labelId, @Body Label label);
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/api/DeckAPI_SSO.java b/app/src/main/java/it/niedermann/nextcloud/deck/api/DeckAPI_SSO.java
index 8e897d1cd..867ab883a 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/api/DeckAPI_SSO.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/api/DeckAPI_SSO.java
@@ -75,7 +75,7 @@ public class DeckAPI_SSO implements DeckAPI {
     }
 
     @Override
-    public Observable<List<Board>> getBoards(Date lastSync) {
+    public Observable<List<Board>> getBoards(String lastSync) {
         NextcloudRequest request = buildRequest(GET, "boards", lastSync).build();
 
         return nextcloudAPI.performRequestObservable(TypeToken.getParameterized(List.class, Board.class).getType(), request);
@@ -102,19 +102,19 @@ public class DeckAPI_SSO implements DeckAPI {
     }
 
     @Override
-    public Observable<Stack> getStack(long boardId, long id, Date lastSync) {
+    public Observable<Stack> getStack(long boardId, long id, String lastSync) {
         NextcloudRequest request = buildRequest(GET, "boards/{boardId}/stacks/{stackId}", lastSync, boardId, id).build();
         return nextcloudAPI.performRequestObservable(Stack.class, request);
     }
 
     @Override
-    public Observable<List<Stack>> getStacks(long boardId, Date lastSync) {
+    public Observable<List<Stack>> getStacks(long boardId, String lastSync) {
         NextcloudRequest request = buildRequest(GET, "boards/{boardId}/stacks", lastSync, boardId).build();
         return nextcloudAPI.performRequestObservable(TypeToken.getParameterized(List.class, Stack.class).getType(), request);
     }
 
     @Override
-    public Observable<List<Stack>> getArchivedStacks(long boardId, Date lastSync) {
+    public Observable<List<Stack>> getArchivedStacks(long boardId, String lastSync) {
         NextcloudRequest request = buildRequest(GET, "boards/{boardId}/stacks/archived", lastSync, boardId).build();
         return nextcloudAPI.performRequestObservable(TypeToken.getParameterized(List.class, Stack.class).getType(), request);
     }
@@ -140,13 +140,13 @@ public class DeckAPI_SSO implements DeckAPI {
     }
 
     @Override
-    public Observable<Card> getCard(long boardId, long stackId, long cardId, Date lastSync) {
+    public Observable<Card> getCard(long boardId, long stackId, long cardId, String lastSync) {
         NextcloudRequest request = buildRequest(GET, "boards/{boardId}/stacks/{stackId}/cards/{cardId}",lastSync, boardId, stackId, cardId).build();
         return nextcloudAPI.performRequestObservable(Card.class, request);
     }
 
     @Override
-    public Observable<Label> getLabel(long boardId, long labelId, Date lastSync) {
+    public Observable<Label> getLabel(long boardId, long labelId, String lastSync) {
         NextcloudRequest request = buildRequest(GET, "boards/"+boardId+"labels/"+labelId, lastSync).build();
         return nextcloudAPI.performRequestObservable(Label.class, request);
     }
@@ -180,7 +180,7 @@ public class DeckAPI_SSO implements DeckAPI {
     }
 
     @Override
-    public Observable<Board> getBoard(long id, Date lastSync) {
+    public Observable<Board> getBoard(long id, String lastSync) {
         NextcloudRequest request = buildRequest(GET, "boards/" + id, lastSync).build();
         return nextcloudAPI.performRequestObservable(Board.class, request);
     }
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/api/RequestHelper.java b/app/src/main/java/it/niedermann/nextcloud/deck/api/RequestHelper.java
index 917cabdc6..687527717 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/api/RequestHelper.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/api/RequestHelper.java
@@ -9,66 +9,32 @@ import java.util.concurrent.LinkedBlockingQueue;
 
 import io.reactivex.Observable;
 import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
 
 public class RequestHelper {
-    private static Queue<PendingRequest> requestQueue = new LinkedBlockingQueue<>();
 
     public static <T> void request(final Activity sourceActivity, final ApiProvider provider, final ObservableProvider<T> call, final IResponseCallback<T> callback){
 
-        if (!provider.isConnected()){
+        if (provider.getAPI() == null){
             provider.initSsoApi(new NextcloudAPI.ApiConnectedListener() {
-                @Override
-                public void onConnected() {
-                    requestQueue.add(new PendingRequest(sourceActivity, call.getObservableFromCall(), callback));
-                    while (!requestQueue.isEmpty()){
-                        PendingRequest pendingRequest = requestQueue.poll();
-                        runRequest(pendingRequest.getSourceActivity(), pendingRequest.getRequest(), pendingRequest.getCallback());
-                    }
-                }
-
+                @Override public void onConnected() { }
                 @Override
                 public void onError(Exception e) {
                     callback.onError(e);
                 }
             });
-        } else {
-            runRequest(sourceActivity, call.getObservableFromCall(), callback);
         }
-    }
 
-    private static <T> void runRequest(final Activity sourceActivity, final Observable<T> request, final IResponseCallback<T> callback){
-        new Thread(() -> {
-                ResponseConsumer<T> cb = new ResponseConsumer<T>(sourceActivity, callback);
-                request.subscribe(cb, cb.getExceptionConsumer());
-        }).start();
+        runRequest(sourceActivity, call.getObservableFromCall(), callback);
     }
 
-    private static class PendingRequest  <T> {
-        private Observable<T> request;
-        private Activity sourceActivity;
-        private IResponseCallback<T> callback;
-
-        public PendingRequest(Activity sourceActivity, Observable<T> request, IResponseCallback<T> callback) {
-            this.request = request;
-            this.callback = callback;
-            this.sourceActivity = sourceActivity;
-        }
-
-        public Observable<T> getRequest() {
-            return request;
-        }
-
-        public IResponseCallback<T> getCallback() {
-            return callback;
-        }
-
-        public Activity getSourceActivity() {
-            return sourceActivity;
-        }
+    private static <T> void runRequest(final Activity sourceActivity, final Observable<T> request, final IResponseCallback<T> callback){
+        ResponseConsumer<T> cb = new ResponseConsumer<>(sourceActivity, callback);
+        request.subscribeOn(Schedulers.newThread())
+                .subscribe(cb, cb.getExceptionConsumer());
     }
 
 
-
     public interface ObservableProvider <T> {
         Observable<T> getObservableFromCall();
     }
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java
index a395c45f8..635b4b764 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java
@@ -3,9 +3,15 @@ package it.niedermann.nextcloud.deck.persistence.sync.adapters;
 import android.app.Activity;
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.util.Log;
 
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import it.niedermann.nextcloud.deck.DeckConsts;
 import it.niedermann.nextcloud.deck.R;
@@ -18,6 +24,8 @@ import it.niedermann.nextcloud.deck.model.Stack;
 
 public class  ServerAdapter implements IPersistenceAdapter {
 
+    private static final DateFormat API_FORMAT = new SimpleDateFormat("E, d MMM yyyy hh:mm:ss z");
+
     private Context applicationContext;
     private ApiProvider provider;
     private Activity sourceActivity;
@@ -31,8 +39,20 @@ public class  ServerAdapter implements IPersistenceAdapter {
                 applicationContext.getString(R.string.shared_preference_last_sync), Context.MODE_PRIVATE);
     }
 
+
+    private String getLastSyncDateFormatted() {
+        String lastSyncHeader = API_FORMAT.format(getLastSync());
+        // omit Offset of timezone (e.g.: +01:00)
+        if (lastSyncHeader.matches("^.*\\+[0-9]{2}:[0-9]{2}$")) {
+            lastSyncHeader = lastSyncHeader.substring(0, lastSyncHeader.length()-6);
+        }
+        Log.d("deck lastSync", lastSyncHeader);
+        return lastSyncHeader;
+    }
+
     private Date getLastSync() {
-        return null;
+        return new Date(1000000000000l);
+        //return null;
         // FIXME: reactivate, when lastSync is working in REST-API
 //        Date lastSync = new Date();
 //        lastSync.setTime(lastSyncPref.getLong(DeckConsts.LAST_SYNC_KEY, 0L));
@@ -41,7 +61,7 @@ public class  ServerAdapter implements IPersistenceAdapter {
 
     @Override
     public void getBoards(long accountId, IResponseCallback<List<Board>> responseCallback) {
-        RequestHelper.request(sourceActivity, provider, () -> provider.getAPI().getBoards(getLastSync()), responseCallback);
+        RequestHelper.request(sourceActivity, provider, () -> provider.getAPI().getBoards(getLastSyncDateFormatted()), responseCallback);
     }
 
     @Override
@@ -61,12 +81,12 @@ public class  ServerAdapter implements IPersistenceAdapter {
 
     @Override
     public void getStacks(long accountId, long boardId, IResponseCallback<List<Stack>> responseCallback) {
-        RequestHelper.request(sourceActivity, provider, () -> provider.getAPI().getStacks(boardId, getLastSync()), responseCallback);
+        RequestHelper.request(sourceActivity, provider, () -> provider.getAPI().getStacks(boardId, getLastSyncDateFormatted()), responseCallback);
     }
 
     @Override
     public void getStack(long accountId, long boardId, long stackId, IResponseCallback<Stack> responseCallback) {
-        RequestHelper.request(sourceActivity, provider, () -> provider.getAPI().getStack(boardId, stackId, getLastSync()), responseCallback);
+        RequestHelper.request(sourceActivity, provider, () -> provider.getAPI().getStack(boardId, stackId, getLastSyncDateFormatted()), responseCallback);
     }
 
     @Override
@@ -86,7 +106,7 @@ public class  ServerAdapter implements IPersistenceAdapter {
 
     @Override
     public void getCard(long accountId, long boardId, long stackId, long cardId, IResponseCallback<Card> responseCallback) {
-        RequestHelper.request(sourceActivity, provider, () -> provider.getAPI().getCard(boardId, stackId, cardId, getLastSync()), responseCallback);
+        RequestHelper.request(sourceActivity, provider, () -> provider.getAPI().getCard(boardId, stackId, cardId, getLastSyncDateFormatted()), responseCallback);
     }
 
     @Override
['app/build.gradle', 'app/src/main/java/it/niedermann/nextcloud/deck/api/ApiProvider.java', 'app/src/main/java/it/niedermann/nextcloud/deck/api/DeckAPI.java', 'app/src/main/java/it/niedermann/nextcloud/deck/api/DeckAPI_SSO.java', 'app/src/main/java/it/niedermann/nextcloud/deck/api/RequestHelper.java', 'app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java']