f-miyu / Plugin.CloudFirestore

MIT License
121 stars 44 forks source link

Offline SetDataAsync Hangs #53

Open barrysohl opened 3 years ago

barrysohl commented 3 years ago

When offline, calling await IDocumentReference.SetDataAync() or UpdateDataAsync() hangs indefinitely. However, upon force quitting the app and relaunching, we see that the data did actually get persisted.

Are we doing something wrong here? It is mission critical that our app support offline mode. Thanks in advance.

barrysohl commented 3 years ago

I should add that the problem still occurs even if DisableNetwork() has been called, which should in theory immediately force all writes to be to local cache.

f-miyu commented 3 years ago

SetDataAync or UpdateDataAsync wait until the data is written to the server database. If you need not do something after the server database update, you should call these without await. if you need, you should use callback method, ContinueWith.

document.SetDataAync(new { Value = 100 });

document.UpdateDataAsync(new { Value = 100 })
    .ContinueWith(t =>
    {
        if (t.IsFaulted)
        {
            System.Diagnostics.Debug.WriteLine(t.Exception);
        }
    });
barrysohl commented 3 years ago

Thanks for the response! I do need to wait for the write to complete. And this works fine when there’s a network connection. However, with persistence enabled and no network connection, the write should be to local cache, which returns almost immediately. I would expect these calls to wait for the write to complete (whether remote or local) and then return. Is that not the case?

joechihe commented 3 years ago

Hi @barrysohl, have you tried to enable persistence enabled? I added this (iOS case) in the app delegate:

var optionsFirebase = new FirestoreSettings(); optionsFirebase.PersistenceEnabled = true; Firestore.SharedInstance.Settings = optionsFirebase;

I'm reading works perfectly, it loads data from local cache when not connection, otherwise gets data from cloud. *Be sure to add that code after: Firebase.Core.App.Configure();

Let me know if that works for you

barrysohl commented 3 years ago

@joechihe Thanks, but we definitely have persistence enabled, and it is definitely after Configure(). In fact persistence is is working, that's not the issue. It's that when offline, Firebase seems to be checking the network and waiting for a timeout before proceeding with the query. We have lots of small queries, so this results in a huge delay. If we manually check a connection and then use the Async version if connected, otherwise not, then that's the only way for us to get it to work as expected.

f-miyu commented 3 years ago

The snapshot listener is called even when the write is done in offline. Is this all right?

document.AddSnapshotListener((snapshot, error) =>
{
    if (snapshot.Metadata.IsFromCache)
    {
        // do from cache
    }
});

or

document.UpdateDataAsync(new { Value = 100 });
var snapshot = await document.AsObservable().FirstAsync();
barrysohl commented 3 years ago

Unfortunately, changing our entire persistence layer to snapshot listeners would be a -major- re-architecture at this point. In retrospect, I would probably try that from the beginning next time around.