Unable to sync after Amplify.Datastore.clear()

725 views Asked by At

I have a home page that does the initial datastore sync in the init() function. There are QueryPredicates that are based on a variable that can change (on a different page).

So basically, after I start the app, everything syncs correctly. Then, I go to another page and change the value that those QueryPredicates depend on, but the sync doesn't occur. Instead, I get an error (that I'm almost positive is caused from the datastore.clear()).

Here is a look at what the QueryPredicate and value change looks like...

List<String> variableThatChanges = ['initialValue']; // belongs to a global class instance

QueryPredicate sampleTest() {
      QueryPredicate res = Sample.AUTHGROUP
          .eq(variableThatChanges.isEmpty ? '' : variableThatChanges[0]);
      return res;
    }


// And when the value is changed, it's changed like this...
variableThatChanges = ['newValue'].toList(); // Not sure if .toList() is actually necessary or not

And this is the rest of the logic...

// Change the variable value, then...
await Amplify.DataStore.stop();
await Amplify.DataStore.clear();
await Amplify.DataStore.start();
Amplify.DataStore.listen([HubChannel.DataStore], (msg) {// do things with the events});
await Amplify.DataStore.save("basic log message to log the change and initiate sync if hasn't already happened");

NOTE: I actually have these commands wrapped in a try/catch and have some other small things going on so each of the above commands is in it's own function and I call them in the following way...

stopStore().then((_) => clearStore()).then((_) => startStore()).then((_) => listenToHub()).then((_) => logEvent());

The error that is produced is the following:

I/amplify:aws-api(11613): No more active subscriptions. Closing web socket.
W/amplify:aws-api(11613): Thread interrupted awaiting subscription acknowledgement.
W/amplify:aws-api(11613):   at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1081)
W/amplify:aws-api(11613):   at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1369)
W/amplify:aws-api(11613):   at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:278)
W/amplify:aws-api(11613):   at com.amplifyframework.api.aws.SubscriptionEndpoint$Subscription.awaitSubscriptionReady(SubscriptionEndpoint.java:381)
W/amplify:aws-api(11613):   at com.amplifyframework.api.aws.SubscriptionEndpoint.requestSubscription(SubscriptionEndpoint.java:183)
W/amplify:aws-api(11613):   at com.amplifyframework.api.aws.MutiAuthSubscriptionOperation.dispatchRequest(MutiAuthSubscriptionOperation.java:113)
W/amplify:aws-api(11613):   at com.amplifyframework.api.aws.MutiAuthSubscriptionOperation.$r8$lambda$iziEcYpvlINdYbit2it7fDbbt8A(Unknown Source:0)
W/amplify:aws-api(11613):   at com.amplifyframework.api.aws.MutiAuthSubscriptionOperation$$ExternalSyntheticLambda4.run(Unknown Source:2)
W/amplify:aws-api(11613):   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:463)
W/amplify:aws-api(11613):   at java.util.concurrent.FutureTask.run(FutureTask.java:264)
W/amplify:aws-api(11613):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
W/amplify:aws-api(11613):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
W/amplify:aws-api(11613):   at java.lang.Thread.run(Thread.java:1012)
D/TrafficStats(11613): tagSocket(71) with statsTag=0xffffffff, statsUid=-1
E/amplify:aws-datastore(11613): Failure encountered while attempting to start API sync.
...
W/amplify:aws-datastore(11613): API sync failed - transitioning to LOCAL_ONLY.
...
I/amplify:aws-datastore(11613): Orchestrator transitioning from SYNC_VIA_API to LOCAL_ONLY
I/amplify:aws-datastore(11613): Setting currentState to LOCAL_ONLY
I/amplify:aws-datastore(11613): Stopping subscription processor.

Of note, the only other time we use Datastore.clear() in our app is prior to the the user signing out, and the same No more active subscriptions. Closing web socket. message comes up.

Any help at figuring out how to fix this to allow for the re-sync after changing the QueryPredicate value would really be appreciated.

It's weird, a lot of times, if I go back to the homepage the init() code with run again and then things start working as desired. This isn't all the time, but most of the time. The thing about that is, that I believe Amplify.configure() is being called again (which I know isn't recommended to do more than once in the apps lifecycle).

I've tried everything listed above, but can't get the subscription error to go away and the app to re-sync correctly.

The end goal is to be able to clear the datastore and get a fresh sync using the new variable in the QueryPredicate.

1

There are 1 answers

0
Adam T On

After reviewing open tickets in the amplify-flutter github repo I came across this one:

https://github.com/aws-amplify/amplify-flutter/issues/1479

Basically, you can't await Datastore.clear() or Datastore.close() (on Android). It's a bug that is supposed to be being worked on, but the ticket is still open and it'll be a year next month, so who knows when it'll be fixed.

Anyways, one of the suggestions in there is to simply implement a manual delay of 2 seconds after you call Datastore.clear().

I ended up doing this after both of my calls, (Datastore.stop() and Datastore.clear()) and everything works just fine now. It's just a timing issue with the asynchronous functions.

So, as mentioned, this isn't the best solution, but until the amplify-flutter team implements a fix, this seems to be a valid workaround.