How can we know that DataStore has finished the sync?

When doing the first await DataStore.query(MyEntity) after the user logged in, DataStore is returning right away and not waiting for the data to be synced with the cloud.

I want to wait for the sync to be completed and put a loading when the data isn't synced yet.


Solution 1: ferox147

make your model class observable so that it can check for data in realtime

   Amplify.DataStore.observeQuery(MyEntity.classType).listen((event) {
  if (event.isSynced) {//boolean value
    print("Synced Successfully!");
    // even you can get synced data here also
      List< MyEntity> items = event.items;
  } else {
    //Show ProgressBar Here
    print("Fetching Data From Cloud");
  }
});


Solution 2: Lewy

You can listen to events on the datastore channel with Amplify.Hub.listen.

details:

 subscription = Amplify.Hub.listen([HubChannel.DataStore], (dynamic hubEvent) async {
      switch (hubEvent.eventName) {
        case 'networkStatus':
          _amplifyIsUp.value = hubEvent.payload.active;
          break;
        case 'subscriptionsEstablished':
          _amplifyMessage.value = 'Starting to sync from cloud...';
          break;
        case 'syncQueriesStarted':
          _amplifyIsSyncing.value = true;
          _amplifyMessage.value = 'Syncing...';
          break;
        case 'modelSynced':
          ModelSyncedEvent mse = hubEvent.payload;

          _amplifyMessage.value = '${mse.modelName} has been sync\'d from cloud...';
          break;
        case 'syncQueriesReady':
          _amplifyMessage.value = 'Done!';
          _amplifyIsSyncing.value = false;

          ///do your bits here
          onSyncsReady.call();

          break;
        case 'ready':
          _amplifyIsSyncing.value = false;

          break;
        case 'subscriptionDataProcessed':

          SubscriptionDataProcessedEvent sdpe = hubEvent.payload;
                  _amplifyMessage.value = 'Syncing ${sdpe.element.model.classType.modelName()}...';
         if (sdpe.element.model is DeviceStatus) {
            DeviceStatus ds = sdpe.element.model as DeviceStatus;
            if (ds.clientID == _clientService.client.id && ds.status == Status.REQUESTSTATUS) {
              _statusService.performHeartbeat();
              } 
          }
          break;
        case 'outboxMutationEnqueued':
          _amplifyIsSyncing.value = true;
          _amplifyHasDirt.value = true;
          break;
        case 'outboxMutationProcessed':
          OutboxMutationEvent ome = hubEvent.payload;
          _amplifyIsSyncing.value = false;
          break;
        case 'outboxStatus':
          OutboxStatusEvent ose = hubEvent.payload;
          if (ose.isEmpty) {
            _amplifyIsSyncing.value = false;
            _amplifyHasDirt.value = false;
          } else {
            _amplifyHasDirt.value = true;
          }

          break;
      }
    });

boop