How can I get updates from a Firestore document? ReactJS - 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).

Related

How to use the dynamic state in React.js, (from url)

If my data is coming from a url (xml or json) and from that data I have to set the state of my react component. The thing is that data is chaning every 5 to 10 seconds. Its data of traffic passing from a certain location where police thinks that people do over speeding alot. so I have to use that source for setting my state in react and display the cars registration number if speed is more than 100km. So data, (speed, time, registration number) of the vehicals i am getting from url online and it changes. So I want it dynamic, means when it changes, it should be updated in state too.
so should I have to make a call of initializing (componentDidMount) for exmple 500ms or something like it, and how?
I havent tried anything yet, cuz I am confused how to do it.

Efficient Firebase document reading and querying with hooks

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 :)

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.

How to store and exchange big firestore data between seperate components in angular?

I have a long length array of numbers in firestore. This array is also just one of the property of my object model.
3 of my components on different pages need this array;
1st component doesn't need this array but needs another properties of my object model. So i have to fetch it from firestore without any other reason.
-2nd component needs this array to reduce its values and display result on the page.
-3rd component needs to display whole array data.
What is the optimized way to store and exchange these data between those components to avoid any memory leaks or unnecesary firestore calls (free calls are very limited and it makes my web app much more slower)??
I tried to assign this object to my service but hence it is an observable i had to subscribe to it everytime a component needs this data.
Need your help.
Thanks in advance.
I would stay with using the obervables, so you can make sure that the state within your forms stays in sync with your array data. If you start moving copies of your array around you would have to establish additional state management like Ngrx etc. to achieve this. Also Firestore has a caching feature built in, so it's not always reading data from the server.
Cheers,
Lars

Responding to high frequency state changes in React.js / Flux

I have an application which receives messages from a server every 1 second and via socket.io these messages are broadcast to a react component.
My react component is using a flux style architecture, so it calls an action when a message is received which adds (or updates) a record in a collection in a store.
My component monitors changes on the store and then updates the UI when it changes. In this case, it draws a marker on a map.
The problem is that due to the frequency of the updates my component redraws all markers every second, which I don't want.
I'm looking for an approach to allow my map component to respond to changes in a collection in a store, but not have the state update every second.
I thought I could have a collection for the raw data, and then only update the networkGPS collection selectively in my store, but the component seems to change based on any property in the store as they all seem to be part of its state.
In summary I'm looking to:
Collect data every 1 second in raw form and add this data to a store.
Bind a component to a collection in this store which I update only when changes require a UI redraw.
What I think I need to do:
Either:
Avoid putting the raw data into the state of the store (at the moment I'm unsure how to declare a collection which is not part of the state)
OR
Make my component more clever as to when it redraws, so it doesn't try to redraw on each state change.
I'm not sure which is the most appropriate solution for the problem, any info would be gratefully receieved.
Sorry if the question is a little unclear, I'm new to react / flux. Please do ask for any clarifications.
EDIT
At the moment I am getting round this issue by storing an array of the items (map markers in this example) I want my component to display in the component itself :(
When the state changes and render is called, I intercept the state properties, decide if anything needs to change in the collection of markers and only amend them if needed. If no changes are needed, the collection in the component stays the same and no redraw is performed.
This is not ideal, I feel like I should be able to allow my component to respond to only specific state changes but I've not found it yet, still looking for a better answer.
There are a couple of ways to approach this:
1) Use shouldComponentUpdate to compare old props and new props, re-rendering only the new marker states.
2) Switch to a cursor-based state tree that automatically triggers renders only for views that are bound to the specific parts of the state tree that have changed. I believe Baobab is one such library. See also Om (written in ClojureScript) and probably a number of other Flux implementations.
Given the impact of #2 my vote would be to go the route of #1.
I am not quite sure what's the problem that you face with updates every second.
However, the one place where you can queue the updates is between the socket.io and calling the action.
Instead of calling the action every second, you could queue the updates before sending it across to react.

Resources