f-miyu / Plugin.CloudFirestore

MIT License
121 stars 44 forks source link

AddSnapshotListener #42

Closed angelru closed 3 years ago

angelru commented 4 years ago

Hello,

How can I get update of added documents without loading all at once? in this code there are always 3 items in the list Items.

if I manually add a document, there are 4 in my ItemsCollection, but there are always 3 in the list Items, the new one replaces the first one in the list Items.

I have detected that DocumentChangeType.Removed is called, When I just add a document ... I don't understand

CrossCloudFirestore.Current
                     .Instance
                     .GetCollection(Settings.ItemsCollection)
                     .WhereGreaterThanOrEqualsTo("Date", DateTime.Now)
                     .OrderBy("Date", true)
                     .LimitTo(3)
                     .AddSnapshotListener((snapshot, error) =>
                     {
                         if (snapshot != null)
                         {
                             foreach (var documentChange in snapshot.DocumentChanges)
                             {
                                 Item item;
                                 switch (documentChange.Type)
                                 {
                                     case DocumentChangeType.Added:
                                          item = documentChange.Document.ToObject<Item>();
                                          Items.Add(item);
                                         break;
                                     case DocumentChangeType.Modified:
                                         break;
                                     case DocumentChangeType.Removed:
                                         item = documentChange.Document.ToObject<Item>();
                                         var removeItem = Items.FirstOrDefault(f => f.Id == item.Id);
                                         if (removeItem != null)
                                         {
                                             Items.Remove(removeItem);
                                         }
                                         break;
                                 }
                             }
                         }
                     });
angelru commented 4 years ago
   case DocumentChangeType.Removed:
                            item = documentChange.Document.ToObject<Item>();
                            var itemRef = CrossCloudFirestore.Current.Instance
                                               .GetCollection(Settings.ItemsCollection)
                                               .GetDocument(item.Id);

                            itemRef.GetDocument((snapshot, error) =>
                            {
                                if (!snapshot.Exists)
                                {
                                    var removeItem= Items.FirstOrDefault(f => f.Id == item.Id);
                                    if (removeItem != null)
                                    {
                                        Items.Remove(removeItem);
                                    }
                                }
                            });
                            break;
angelru commented 4 years ago

I have successfully implemented real-time pagination, but have noticed that when new elements (BBDD) are added and pagination still doesn't run, sometimes there are elements that repeat, also when pagination is executed and there are still pending elements, if an element new is added (BBDD) and then I scroll sometimes the elements repeat.

Sometimes it happens and sometimes it doesn't, it's very rare

Init:

 queryItems = CrossCloudFirestore.Current.Instance.GetCollection(Settings.ItemsCollection)
                                                  .WhereGreaterThanOrEqualsTo("Date", DateTime.Now.Date)
                                                  .OrderBy("Date", true).LimitTo(limitItems);

            queryItems.AddSnapshotListener((snapshot, error) =>
            {

                QuerySnapshot(snapshot);
            });

LoadMore:

           if (CanLoadMore) return;

                CanLoadMore = true;

                queryItems = queryItems.StartAfter(lastVisibleDocument);

                queryItems.AddSnapshotListener((snapshot, error) =>
                {
                    if (snapshot.Count is 0)
                    {
                        ItemsThreshold = -1;
                        return;
                    }

                    QuerySnapshot(snapshot);
                    CanLoadMore = false;
                });

QuerySnapshot:

        private void QuerySnapshot(IQuerySnapshot snapshot)
        {
            if (snapshot != null)
            {
                lastVisibleDocument = snapshot.Documents.LastOrDefault();

                foreach (var documentChange in snapshot.DocumentChanges)
                {
                    Item item;
                    switch (documentChange.Type)
                    {
                        case DocumentChangeType.Added:
                            item = documentChange.Document.ToObject<Item>();
                            Items.Add(item);
                            break;
                        case DocumentChangeType.Modified:
                            break;
                        case DocumentChangeType.Removed:
                            break;
                    }
                }
            }
        }
Denaindra commented 3 years ago

Hi @angelru

Cool with your findings, Awsome

May i know for the realtime where should we implement this AddSnapshotListener methods ? Form each platform or VM ?

angelru commented 3 years ago

@Denaindra What do you need to know exactly? The AddSnapshotListener should be executed when loading your page, then it should handle all listeners in OnSleep OnResume events

for example: https://github.com/f-miyu/Plugin.CloudFirestore/issues/64

Denaindra commented 3 years ago

@angelru

I need to know where should I implement the AddSnapshotListener in my code.

Is that need to separate implement in the each platforms or in the viewmodel, or app.xml.cs

angelru commented 3 years ago

@Denaindra

if you use xamarin forms and the MVVM pattern you have to apply AddSnapshotListener it in the viewmodel, then you have to handle the listeners in the app.cs in the OnSleep and OnResume methods as I put above.

here you have information https://github.com/f-miyu/Plugin.CloudFirestore/issues/64

Denaindra commented 3 years ago

@angelru

Thanks for your clarifications