Efficient Firebase document reading and querying with hooks - reactjs

I am currently using queries to get the initial state of a user. They potentially could have thousands of individual documents that don't need to be set up via hooks.
My current approach is mostly working, however it does mean there is a double read on the documents that I create the hook on.
query(
collection(firestore, "userDocs"),
where("ownedBy", "==", userId),
orderBy(documentId()),
limit(6)
)
This is my initial query, I am using react infinite scrolling to then fetch more as they scroll down. Each of these documents is a rendered component in React.
Within that component I then setup a hook to pretty much go and get the same data that I just did.
setCol(doc(firestore, "userDocs", userDocId),{
snapshotListenOptions: { includeMetadataChanges: true },
})
They both set a document state on the component, once on load, and when ever the firebase hook goes off. I am using a react firebase package here for hook simplification.
My question is, how can I get this hook functionality which I really need, but stop this initial read from the firebase hook. If I don't do the initial query for the documents, I don't get the data I need to make the hooks. And also an approach I tried of just using hooks passed to the user doc component was much slower than my query based approach because firebase queries are really fast than singular document reads.
I am basically trying to prevent a second read when the hook on the document is created because its data will just be the data I got back from the query and isn't very efficient. I have seen some implementations that get around this using a timestamp updated at field, but does that require me to perform an extra write on the documents that I've just queried?
When I update the document that triggers the hook its possible I can pop a timestamp field in then but Im not sure how that solves my initial read problem.
Many thanks for any suggestions :)

Related

How can I decrease the number of firestore reads with React context?

I'm making a firestore application with ReactJS, I made some tricks to decrease the number of document reads of it, I already created a context with snapshots, basically I set a query inside a function and I pass it's result through the context, so I won't need to call the query again, and every update I have in the collection, the snapshot shows me.
But I want more, my question is: Do I have more tricks to use with react context to decrease the number of document reads?
For example, can I pass a collection reference as context?
Like this:
const collectionReference = collection(db, "collectionName");

Redux Tool Kit Query: Need same data in different two components but without duplicate requests

I'm new to rtk and rtk query , I'm using rtk query. I have two components I need the same data for each, I do not want to call the function twice in each component to get the same data, is there a way to only call it one time then for better performance?
for example
I'm calling getCartItems in one of those components but I need the same data in the nav bar component to get its count
so I don't want to send the same request again am I right ?
When you query data, redux toolkit query will store those queries inside queries of slice in the redux store:
this is stored in the global state, so anytime you make a request to an endpoint, rtk query first checks this property and if there is same query, it does not add a new query, it de-duplicates (eliminates duplicate) and returns the result of the original query
If you call the same query hook with the same argument in multiple components, only one request will be made. Cache entries are shared internally, that's pretty much the point of RTK Query.
Try it out & take a look at your network devtools :)

How can I get updates from a Firestore document? ReactJS

I have the following problem:
I have a document with data in firestore. I collect the data from that document and show it on the screen, everything is perfect. But, if I add data or modify it, how can I get the new data at the moment the document has been updated, without continuously checking if there have been changes? Since it would exceed the firestore reading limit. That is, it receives a kind of notification that there is new data, checks it and updates itself. I've tried with a state variable(useState) inside a useEffect but I can't find a way to make it work.
I hope you can help me.
first at all try to make a get right after your create or update action on the document.
If you don't want to do that, you can read this part of the documentation of firestore and try to create a custom hook calling it directly on the useEffect (in order to get every update in the lifecycle).

Subscription Refetch Updating Data

I wanted to get your opinion on something.
I'm trying to understand how a subscription works. however, I couldn't find a way to pull an array of objects in a subscription. for example, if I use createMany, I can not return all the result via subscription.
The second issue is if I return a single item for example if it's a new item, I have to "manually (air quote)" add that item to the list that is already displayed. But this feels to me I don't actually display real-time true data.
So my question is using something like
useEffect(() => {
// refetching original query when subscription is triggered
refetch();
}, [updatedNotificationData]);
would there be any downside like hitting up the server more than I should? let's say every time there is a refetching happens I might be pulling thousands of notifications (I know there is caching but still) or is there a better way to deal with bringing new data.
Also, I tried adding subscribed data to the original list but for some reason react adds 2 of the same item every time.
Thanks in advance if you can give me in the right direction.
if I use createMany, I can not return all the result via subscription.
That shouldn't be a problem if you define the return type of the subscription as array.
type Subscription{
onChange:[ObjectType]
}
It would allow you to avoid fetching again but updating cache can get a bit complicated.
Also, I tried adding subscribed data to the original list but for some reason react adds 2 of the same item every time.
In case you are using the the subscribeToMore method it's not really reacts fault but the way how the updateQuery method works: github issue regarding this.
My workaround was to subscribe via the useSubscription hook and handle the cache modifications inside the onSubscriptionData callback apollo documentation and also setting the useQuery hooks skip option once I get the data so it wont query on each rerender.

React Query: When to use useInfiniteQuery or usePaginatedQuery for pagination

I have a table like this
which renders paginated items. The exact number of the times is unknown at the time of the API being called. So for handling pagination of a table like this. it is better to use useInfiniteQuery or usePaginatedQuery from React Query?
I am really struggling to understand the differences of the use cases for these two APIs here
As far as I understand by reading a bit of the docs, usePaginatedQuery will return resolvedData that just equals the last successeful page's data, it won't concatenade the last page's data to the data you already had. On the other hand, useInfiniteQuery does this with fetchMore.

Resources