f-miyu / Plugin.CloudFirestore

MIT License
121 stars 44 forks source link

Major DateTime issues #55

Open vincooys opened 3 years ago

vincooys commented 3 years ago

Ever since I updated to the latest version of this plugin, it has essentially completely broken my app :-/

I'm currently retrieving items from firestore, and storing them locally in a Sqlite database. When users return to the app, I am getting the max date time from sqlite, and trying to retrieve documents greater than this date.

This is either not pulling anything, or it's pulling multiple documents that are either BEFORE the time stored in Sqlite, or appear to be the same item(s) every time.

var latestAnswersReference = await _firestore.GetCollection(Answer.CollectionPath)
                                                          .WhereEqualsTo(new FieldPath("user_id"), userId)
                                                          .WhereEqualsTo(new FieldPath("partner_id"), partnerId)
                                                          .WhereGreaterThan(new FieldPath("date_answered"), lastAnswerDate)
                                                          .GetDocumentsAsync()
                                                          .ConfigureAwait(false);

As an example: during my tests, the max local date time stored is 1:40 AM (as a DateTime object). The timestamp is stored in firestore as 1:40 AM UTC-4.

I run the above query, and then convert the TimeStamp into a DateTime object and store it locally.

//Convert server timestamp into local time and save in local sqlite database
//ServerDateAnswered is a TimeStamp object, answer.DateAnswered is a DateTime object
answer.DateAnswered = answer.ServerDateAnswered.ToDateTime();

When I run the query again, it pulls the 1:40 AM document from the server again. No matter how I convert dates, it always pulls this document. I've tried converting the TimeStamp by doing a ServerDateAnswered.ToLocalDate(). I've tried converting the lastAnswerDate in the query to a DateTimeOffset, and to a timestamp object. I've tried calculating it to the epoch and sending that into the query. But every. single. time. I get the 1:40 AM document. When my users have hundreds of answers saved, this is incurring A TON of reads in the database.

What am I doing wrong? This was working fine before the latest update to the plugin..

vinco83 commented 3 years ago

I think I finally solved this.

Unfortunately, Sqlite doesn't allow you to store a Timestamp object. I was attempting to convert the returned timestamp into a DateTime object, and then doing a GreaterThan query based on that. However, this wouldn't work no matter how I converted the timestamp object for storing in Sqlite.

So I just created two new properties to store in Sqlite: TimestampSeconds, and TimestampNanoseconds, and I'm reconstructing a Timestamp object based on those values to use in my query.

Perhaps there a bug in this plugin when converting a Timestamp object to a DateTime object, or perhaps I just have a fundamental misunderstanding of how the Timestamp objects work--but I'm just glad I am finally getting accurate results!

Btw, thank you for all of your work on these plugins @f-miyu!!

angelru commented 3 years ago

52 May be related ?