-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added proper query serializer #75
base: master
Are you sure you want to change the base?
Conversation
src/classes/Fuego.ts
Outdated
@@ -11,6 +11,7 @@ export class Fuego { | |||
public auth: typeof firebase.auth | |||
public functions: typeof firebase.functions | |||
public storage: typeof firebase.storage | |||
public DocumentReference = firebase.firestore.DocumentReference |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I managed to fix compatibility with Firebase 8.x
by placing the DocumentReference
inside the Fuego class.
So, for those that use 8.x
, all they need to do is add the DocumentReference
to their Fuego instance.
It's not a breaking change if they don't add it, because people with a custom Fuego will still be able to use the library like usual, and their document references won't be serialized properly (which it didn't before anyway) until they add DocumentReference
Creating the document reference in my older comment is also done using fuego.db.doc
instead now.
Does this seem like a good solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing this via the Fuego
instance is ideal. It's nice to have an entry-point that manages all things compatibility. Does 8.x remove this type altogether or just rename it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't remove it, but since imports are changed from import * as firebase from
to import firebase from
it means the version different messes things up. By providing the right firebase in Fuego, this doesn't happen.
I see Fuego as a very nice compatibility interface between different versions, and because we pass in the functions and storage that way, why not pass in firestore as well so we have access to the right variables.
src/types/Query.ts
Outdated
*/ | ||
endBefore?: number | ||
|
||
// THESE ARE NOT JSON SERIALIZABLE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we're at it, might be a good time to knock these out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely yes! I'll look into that right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you know if there is a way to construct a snapshot?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've managed to get it working with snapshots. Instead of serializing and re-constructing the snapshot, I store it away in a map and then fetch it when deserializing.
I do not know how using multiple useCollection with the same snapshots will affect this. If it has problems, we could try changing the serializer from static to have one serializer per useCollection. Then, we can store the fuego inside the Serializer rather than passing it as a parameter, and we don't have to worry about other hooks interfering with the cache.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nandorojo Before merging, we need to investigate this above. Will it be a problem?
What's the status on this PR? I noticed we can't use document refs in where conditions right now. This looks like it would fix it. |
Hey, I've been really busy with work so I haven't had time to finish reviewing and testing it out. I'll do my best to get to it soon. |
@nandorojo that would be amazing. Thank you for the extremely quick response. |
You got it |
As I said in one of my comments, we should investigate if the cache could cause problems when using multiple hooks at the same time before merging this.
|
This comment has been minimized.
This comment has been minimized.
While this PR don't get merged, there are alternatives to query with |
// Deserializer function for query | ||
public static deserializeQuery<Data extends object = {}>( | ||
queryString: string, | ||
fuego: Fuego |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is technically a global variable, since it's set from the config step of this library. I wonder if we should just import that directly. I'll think about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for passing the fuego is to ensure the same version of firebase is used, because there are differences in the typings. I had trouble using it with my project due to this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should still be solved at the initialization step, with something like this: #59 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do use my own Fuego instance, but I ran into problems with DocumentReference not being available in different versions of firebase, or at least available in different locations. If you have any suggested changes to fix this then that is welcome, the sooner we can merge this the better.
@brunoalano at the moment, not that I know of |
Will this be merged? |
} | ||
// Date: Inject serializer options if not specified | ||
if (where[2] instanceof Date && !where[3]) { | ||
return [...where.slice(0, 3), { type: 'date' }] as WhereItem<Doc> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this turn the date into a serializable value, such as milliseconds or a string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or I suppose JSON.stringify at the last step can handle Dates, never mind
I can give it a final look with comments I left |
How can I help with this PR? |
You could test all the changes with real data in your app, and give input to my open comments to help push it along |
To be honest, I do not see any reason to not merge this at this point. I've been using it in prod for a while.
However, this may only be a problem when serializing DocumentReference:
|
Have you tried using E.g. something like this from the examples doesn't seem to work const { data } = useCollection('users', {
where: ['name', '==', 'fernando'],
limit: 10,
orderBy: ['age', 'desc'],
listen: true,
}) |
In fact, on further inspection, this looks like a more general problem with just using a Might be related to #77. |
My bad. This looks like it was due to a missing index. The error for this isn't surfaced anywhere though, and would be passed as the second arg to this querySnapshot-handling function.
|
The current method of storing the query in the cache is a simple
JSON.stringify
andJSON.parse
. This has some problems; you cannot serialize certain objects, most notably Dates. Querying for dates in firestore is impossible with the current method because it is converted into a string due to the JSON serializer.This PR implements the base of a proper serializer, that will maintain dates in the query, allowing you to correctly query for dates in your database.
It also allows future objects to be serialized correctly, by simply adding specific logic to the serializer.