'ObservableCollection count resets to 0 from second function call in Xamarin forms app

There is a Dependency class in android that has these two functions

1. public void OnEvent(Java.Lang.Object obj, FirebaseFirestoreException error)
        {
try
            {
                var docs = (QuerySnapshot)obj;
                visitorDetails.Clear();
                foreach (var doc in docs.Documents)
                {
                    Console.WriteLine(doc.Get("VisitorName").ToString());
                        var visitordetails = new VisitorDetails
                    {
                        Name = doc.Get("VisitorName").ToString(),
                        ContactNumber = doc.Get("VisitorContact").ToString(),
                        VehicleNumber = doc.Get("VisitorVehicleNo").ToString(),
                        IsApproved = doc.Get("VisitorIsApproved").ToString(),
                        IsActive = doc.Get("VisitorIsActive").ToString(),
                        Purpose = doc.Get("PurposeOfVisit").ToString(),
                        Email = doc.Get("VisitorEmail").ToString(),
                        FromDate = toDatetime(doc.GetDate("FromDate") as Date),
                        ToDate = toDatetime(doc.GetDate("ToDate") as Date),
                        docID = doc.Id
                    };
                    visitorDetails.Add(visitordetails);
                }
                Console.WriteLine("onevent - " + visitorDetails.Count.ToString());
                HasReadCompleted = true;                
                MessagingCenter.Send<object, string>(this, "HasChanges", "true");
            }
            catch (FirebaseFirestoreException error1)
            {
                Console.WriteLine(readMode + error1.Message);
                HasReadCompleted = false;
            }
}
2. public async Task<ObservableCollection<VisitorDetails>> ReadVisitorDetails()
        {
            try
            {                                              
                Console.WriteLine("return - " + visitorDetails.Count.ToString());
                return visitorDetails;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return null;
            }
        }

In my PCL ViewModel class

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using ULTIMATE_VMS.Models;
using ULTIMATE_VMS.ViewModels.Helpers;
using ULTIMATE_VMS.Views;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace ULTIMATE_VMS.ViewModels
{
    public class VMSPageViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        private static IFirestore firestore;
        #region properties     
        private string fullname;
        public string FullName
        {
            get
            {
                return fullname;
            }
            set
            {
                fullname = value;
                OnPropertyChanged("FullName");
                OnPropertyChanged("CanApprove");
            }
        }
        private string phonenumber;
        public string Phone_Number
        {
            get
            {
                return phonenumber;
            }
            set
            {
                phonenumber = value;
                OnPropertyChanged("Phone_Number");
                OnPropertyChanged("CanApprove");
            }
        }
        private string emailid;
        public string Email_ID
        {
            get
            {
                return emailid;
            }
            set
            {
                emailid = value;
                OnPropertyChanged("Email_ID");
                OnPropertyChanged("CanApprove");
                OnPropertyChanged("CanSearch");
            }
        }
        private string companyname;
        public string Company_Name
        {
            get
            {
                return companyname;
            }
            set
            {
                companyname = value;
                OnPropertyChanged("Company_Name");
                OnPropertyChanged("CanApprove");
            }
        }
        private string vehiclenumber;
        public string Vehicle_Number
        {
            get
            {
                return vehiclenumber;
            }
            set
            {
                vehiclenumber = value;
                OnPropertyChanged("Vehicle_Number");
                OnPropertyChanged("CanApprove");
            }
        }
        private DateTime fromdate;
        public DateTime From_Date
        {
            get
            {
                return fromdate;
            }
            set
            {
                fromdate = value;
                OnPropertyChanged("FromDate");
                OnPropertyChanged("CanApproveExecute");
            }
        }
        private DateTime todate;
        public DateTime To_Date
        {
            get
            {
                return todate;
            }
            set
            {
                todate = value;
                OnPropertyChanged("ToDate");
                OnPropertyChanged("CanApproveExecute");
            }
        }
        private string purpose;
        public string Vis_Purpose
        {
            get { return purpose; }
            set { purpose = value; }
        }

        private ObservableCollection<VisitorDetails> visitordets;
        public ObservableCollection<VisitorDetails> visitordetails
        {
            get
            {
                return visitordets;
            }
            set
            {
                visitordets = value;
                OnPropertyChanged("visitordetails");
            }
        }

        private ObservableCollection<VisitorDetails> upcomingvisitors;
        public ObservableCollection<VisitorDetails> upcomingVisitors
        {
            get
            {
                return upcomingvisitors;
            }
            set
            {
                upcomingvisitors = value;
                OnPropertyChanged("visitordetails");
            }
        }

        private ObservableCollection<VisitorDetails> apprdetails;
        public ObservableCollection<VisitorDetails> approvedetails
        {
            get
            {
                return apprdetails;
            }
            set
            {
                apprdetails = value;
                OnPropertyChanged("approvedetails");
            }
        }
        private IList<VisitorDetails> details;
        public IList<VisitorDetails> Details { 
            get { 
                return details; 
            } 
            set 
            { 
                details = value; 
            } 
        }

        private bool hasapproval;

        public bool HasApprovals
        {
            get { return hasapproval; }
            set { hasapproval = value; }
        }

        private bool hasupcoming;

        public bool HasUpcoming
        {
            get { return hasupcoming; }
            set { hasupcoming = value; }
        }

        private bool hasnoupcoming;

        public bool HasNoUpcoming
        {
            get { return hasnoupcoming; }
            set { hasnoupcoming = value; }
        }

        private bool isrefreshing;

        public bool IsRefreshing
        {
            get { return isrefreshing; }
            set { isrefreshing = value; }
        }

        private VisitorDetails selectedItem;

        public VisitorDetails SelectedItem
        {
            get { return selectedItem; }
            set { selectedItem = value; }
        }

        private bool haslogs;

        public bool HasLogs
        {
            get { return haslogs; }
            set { haslogs = value; }
        }
        private bool hasnologs;

        public bool HasNoLogs
        {
            get { return hasnologs; }
            set { hasnologs = value; }
        }
        private string condoname;
        public string Condo_Name
        {
            get
            {
                return condoname;
            }
            set
            {
                condoname = value;
                OnPropertyChanged("Condo_Name");
                OnPropertyChanged("CanApply");
                OnPropertyChanged("CanSearch");
            }
        }
        private string blockno;
        public string Block_No
        {
            get
            {
                return blockno;
            }
            set
            {
                blockno = value;
                OnPropertyChanged("Block_No");
                OnPropertyChanged("CanApply");
                OnPropertyChanged("CanSearch");
            }
        }
        private string unitno;
        public string Unit_No
        {
            get
            {
                return unitno;
            }
            set
            {
                unitno = value;
                OnPropertyChanged("Unit_No");
                OnPropertyChanged("CanApply");
                OnPropertyChanged("CanSearch");
            }
        }
        private int tabindex;

        public int TabIndex
        {
            get { return tabindex; }
            set { tabindex = value; }
        }

        #endregion
        public ICommand Accept { protected set; get; }
        public ICommand Decline { protected set; get; }
        public ICommand CallVisitor { protected set; get; }
        public ICommand RefreshPage { protected set; get; }
        public ICommand ItemTappedCommand { get; private set; }
        public ICommand ApproveCommand { protected set; get; }
        public ICommand SearchCommand { protected set; get; }
        public ICommand clearfields { protected set; get; }

        private UserDetails userdetails;
        public VMSPageViewModel()
        {
            firestore = DependencyService.Get<IFirestore>();
            tabindex = 0;
            OnPropertyChanged("TabIndex");
            Accept = new Command<VisitorDetails>(OnAcceptClick);
            Decline = new Command<VisitorDetails>(OnDeclineClick);
            CallVisitor = new Command<VisitorDetails>(OnCallClick);
            RefreshPage = new Command(OnrefClick);
            ItemTappedCommand = new Command(ItemTapped);
            clearfields = new Command(clearFields);
            ApproveCommand = new Command(OnApproveClick, CanApproveExecute);
            SearchCommand = new Command(OnSearchClick, CanSearchExecute);        
            visitordetails = new ObservableCollection<VisitorDetails>();
            approvedetails = new ObservableCollection<VisitorDetails>();
            upcomingVisitors = new ObservableCollection<VisitorDetails>();
            Details = new ObservableCollection<VisitorDetails>();
            userdetails = new UserDetails();
            hasapproval = false;
            hasupcoming = false;
            hasnoupcoming = !hasupcoming;
            haslogs = false;
            hasnologs = !haslogs;
            OnPropertyChanged("HasUpcoming");
            OnPropertyChanged("HasNoUpcoming");
            OnPropertyChanged("HasApprovals");
            OnPropertyChanged("HasLogs");
            OnPropertyChanged("HasNoLogs");

            From_Date = DateTime.Now;
            To_Date = DateTime.Now;

            CheckForChanges();

            getuserDetails();

            firestore.InitListners();
            //ProcessData();
        }

        public void CheckForChanges()
        {
           MessagingCenter.Subscribe<object, string>
                (this, "HasChanges", (sender, status) =>
                {
                    if(status=="true" && userdetails != null)
                    {
                        ProcessData();
                    }                
                });
        }

       public async void getuserDetails()
        {
            userdetails = null;
            userdetails = await firestore.ReadUserDetails();
        }     
        public async void OnApproveClick(Object parameter)
        {
            UserDetails userdetails = await firestore.ReadUserDetails();

            await firestore.AddVisitorDetails(new VisitorDetails
            {
                Name = FullName,
                Email = Email_ID,
                ResEmail = userdetails.Email,
                CondoName = userdetails.CondoName,
                BlockNo = userdetails.BlockNumber,
                UnitNo = userdetails.UnitNo,
                ContactNumber = Phone_Number,
                CompanyName = Company_Name,
                VehicleNumber = Vehicle_Number,
                Purpose = Vis_Purpose,
                FromDate = From_Date,
                ToDate = To_Date,
                IsActive = "True",
                IsApproved = "True",
                CreationDate = DateTime.Now
            });
            Console.WriteLine("Visitor Added");
            await Shell.Current.DisplayAlert("Successfull", "Visitor Addedd Successfully", "Ok");

            clearFields();

            tabindex = 0;
            OnPropertyChanged("TabIndex");

            ProcessData();
        }
        public async void OnSearchClick(Object parameter)
        {
            ResidentDetails resdetails = await firestore.ReadUserDetails("Email", Email_ID);

            if (resdetails != null)
            {
                FullName = resdetails.Name;
                Phone_Number = resdetails.ContactNumber;
                Company_Name = resdetails.CompanyName;
                Vehicle_Number = resdetails.VehicleNumber;
                Condo_Name = resdetails.CondoName;
                Block_No = resdetails.BlockNumber;
                Unit_No = resdetails.UnitNo;
            }
        }
        public void clearFields()
        {
            FullName = "";
            Email_ID = "";
            Phone_Number = "";
            Company_Name = "";
            Vehicle_Number = "";
            Vis_Purpose = "";
            Condo_Name = "";
            Block_No = "";
            Unit_No = "";
            From_Date = DateTime.Now;
            To_Date = DateTime.Now;
        }
        private bool CanApproveExecute(object arg)
        {
            return CanApprove;
        }
        public bool CanApprove
        {
            get
            {
                return !string.IsNullOrEmpty(FullName) && !string.IsNullOrEmpty(Phone_Number) && !string.IsNullOrEmpty(Email_ID) && !string.IsNullOrEmpty(Vehicle_Number) && !string.IsNullOrEmpty(Vis_Purpose);
            }
        }
        private bool CanSearchExecute(object arg)
        {
            return CanSearch;
        }
        public bool CanSearch
        {
            get
            {
                return !string.IsNullOrEmpty(Email_ID);
            }
        }
        public void OnrefClick()
        {
            ProcessData();
            isrefreshing = false;
            OnPropertyChanged("IsRefreshing");
        }
        private void OnPropertyChanged(string PropertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
        }
        public async void ProcessData()
        {
            for (int i = 0; i < 20; i++)
            {
                await Task.Delay(1000);
                if (userdetails != null)
                {
                    //Console.WriteLine("Writew success");
                    break;
                }
            }
            hasupcoming = false;
            OnPropertyChanged("HasUpcoming");
            hasnoupcoming = !hasupcoming;
            OnPropertyChanged("HasNoUpcoming");
            try
            {             
                details.Clear();
                details = firestore.ReadVisitorDetails();
                OnPropertyChanged("Details");
                visitordets.Clear();
                upcomingvisitors.Clear();
                apprdetails.Clear();
                
                if (details != null && userdetails != null)
                {
                    foreach (var visitor in details)
                    {
                        if (!visitor.Email.Equals(userdetails.Email))
                        {
                            visitor.FDate = visitor.FromDate.ToString("dd/MM/yyyy");
                            visitor.TDate = visitor.ToDate.ToString("dd/MM/yyyy");
                            visitordets.Add(visitor);
                            if (visitor.IsApproved.Equals("False") && visitor.FromDate.Date >= DateTime.Now.Date)     //Pending approval visitors
                            {
                                apprdetails.Add(visitor);
                                hasapproval = true;
                                OnPropertyChanged("HasApprovals");
                            }
                            if (visitor.IsApproved.Equals("True") && visitor.FromDate.Date >= DateTime.Now.Date)
                            {
                                upcomingvisitors.Add(visitor);
                                hasupcoming = true;
                                OnPropertyChanged("HasUpcoming");
                                hasnoupcoming = !hasupcoming;
                                OnPropertyChanged("HasNoUpcoming");
                            }
                        }
                    }
                }
                if (visitordets.Count <= 0)
                {
                    haslogs = false;
                    hasnologs = !haslogs;
                }
                else
                {
                    haslogs = true;
                    hasnologs = !haslogs;
                }
                OnPropertyChanged("HasLogs");
                OnPropertyChanged("HasNoLogs");
                OnPropertyChanged("visitordetails");
                OnPropertyChanged("approvedetails");
                OnPropertyChanged("upcomingVisitors");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Master" + ex.Message);
            }
        }

        public async void OnAcceptClick(VisitorDetails details)
        {
            Console.WriteLine("AcceptClick " + details.docID);
            apprdetails.Remove(details);
            OnPropertyChanged("approvedetails");
            if (apprdetails.Count <= 0)
            {
                hasapproval = false;
                OnPropertyChanged("HasApprovals");
            }
            await firestore.UpdateField(details.docID, "visitorDetails", "VisitorIsApproved", "True");
        }
        public async void OnDeclineClick(VisitorDetails details)
        {
            Console.WriteLine("DeclineClick " + details.docID);
            apprdetails.Remove(details);
            OnPropertyChanged("approvedetails");
            if (apprdetails.Count <= 0)
            {
                hasapproval = false;
                OnPropertyChanged("HasApprovals");
            }
            await firestore.DeleteDoc(details.docID, "visitorDetails");
        }
        public void OnCallClick(VisitorDetails details)
        {
            try
            {
                PhoneDialer.Open(details.ContactNumber);
            }
            catch (ArgumentNullException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch (FeatureNotSupportedException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public async void ItemTapped()
        {
            var visitordetails = new VisitorDetails()
            {
                Name = SelectedItem.Name,
                Email = SelectedItem.Email,
                ContactNumber = SelectedItem.ContactNumber,
                VehicleNumber = SelectedItem.VehicleNumber,
                IsApproved = SelectedItem.IsApproved,
                IsActive = SelectedItem.IsActive,
                Purpose = SelectedItem.Purpose,
                FromDate = SelectedItem.FromDate,
                ToDate = SelectedItem.ToDate,
            };
            await Shell.Current.Navigation.PushAsync(new LogDetailsPage(visitordetails));
            /* await Shell.Current.GoToAsync($"//LogDetailsPage?Name={SelectedItem.Name}&" +
                 $"ContactNumber={SelectedItem.ContactNumber}&" +
                 $"VehicleNumber={SelectedItem.VehicleNumber}&" +
                 $"IsApproved={SelectedItem.IsApproved}&" +
                 $"IsActive={SelectedItem.IsActive}&" +
                 $"Purpose={SelectedItem.Purpose}&" +
                 $"Email={SelectedItem.Email}&" +
                 $"FromDate={SelectedItem.FromDate}&" +
                 $"ToDate={SelectedItem.ToDate}");*/
        }

    }
}

so my PCL class calls ReadVisitorDetails() whenever the MessagingCenter text is true

The first time when it runs the output is fine onevent - 1 return - 1

after the first time return is always 0 onevent - 1 return - 0

visitorDetails is a class variable initialized inside the constructor



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source