Replaying actions in Redux devtools will generate new actions with RxJS - redux

So basically My Angular2 application is using ngrx and rxjs. And also I'm using Redux DevTools chrome extention for debugging purpose.
The thing is when I tried to replay all the actions in Redux DevTools, it always generates new actions automatically. I think the reason is because I'm using a lot of Observables and Subscriptions from rxjs to listen to any store updates and dispatch new actions based on that, and since replaying actions will update the store, it will trigger all those subscriptions. So my question is, is it possible to prevent new actions being generated from replaying actions?

Related

Does Firestore have an in-memory cache for optimistic updates separate from IndexedDB?

I am wondering if IndexedDB is the only cache Firestore uses.
To be clear, I am not talking about persisting data with enableIndexedDbPersistence(). I am talking about an internal store for the sole purpose of optimistic updates when the app is still in state. Is there something similar to redux, svelte store, or InMemoryCache which is run in the background when a subscription is open?
It seems that when I use onSnapShot() for a list of items, and I update an item in the list with setDoc elsewhere, the UI gets updated immediately, optimistically.
Perhaps Firestore is just that quick where the data is sent to the server, changed, and sent back to the client with the UI being updated that quickly, but it seems to me it is an optimistic update.
Does Firestore use any other caching techniques or state management techniques when the app is still running besides IndexedDB?
J
References (maybe releated):
Does Firebase cache the data?
As long as you have an active onSnapShot listener, the Firestore SDK will have a copy of the latest query snapshot for that listener in memory. If you attach another listener to the same (or partially overlapping) data, that listener may get (part of) its data from the existing listener.
So when you perform an update in the same client as where you have a listener, the SDK immediately applies that update to its local copy of the data and fires an event (so that is almost instantly). It then sends the update to the server, which executes it on the backend storage layer. If that update gets rejected (a relatively rare occurrence), the client will revert the change it make locally and fire another event with the corrected state.
An easy way to see this in practice is to perform a write operation that is rejected by your security rules. You'll briefly see the invalid state on the client, before it reverts to the correct state. This invalid state only happens on the client that performs the invalid write, so it's typically fine to ignore it there.

Updating Apollo cache after fetching data on server-side

I spent 4 days in an attempt to get Apollo working with my Next.js app — and encountered a huge dilemma, as it seems.
Here's a very clear and understandable example for React SPA. This is how we update cache using mutation hook.
The mutation hook works with "todos" fields. Here's the excerpt:
fields: {
todos(existingTodos = []) {
This implies that a query has been made before. The data was fetched via GraphQL query on the client-side. And the todos data has been cached as "todos" collection (or field rather).
So, with React SPA it is trivial to update the cache. And the work is easy and straightforward.
Dilemma
In my Next.js app I fetch data on server-side in getServerSideProps() method. The fetched data is passed further to the Page Component as props.
When I perform a mutation on client-side — it's a different, an in-browser Apollo Client instance that doesn't have the cached data. Because that data was fetched using server-side instance.
If it's not possible to access the Apollo server-side cache from the client-side (browser) — can someone recommend a workaround of how to go about Apollo with Next.js?

Firestore: how can I get stream of updates from a server side?

tldr: I need to have Google Cloud Functions on my own backend.
I write application, which uses firebase (especially firestore) as a transport layer between my own backend written on nodejs and client applications.
Sometimes, I need to catch some events from client on backend, but i want to avoid perform http queries directly to my backend (because I need to catch offline status, and other problems). It is better to made some changes in firestore documents, catch that changes on my backend and perform some business logic.
As for now, It can be solved with Cloud Functions, but this solution is not acceptable, because of delay between event and function invocation, and lack of invocation order.
Yet another solution, which is currently used in my project, is to making some changes to firestore document, and adding extra document, called "event" to other collection. On a server side, using firebase-admin sdk, I subscribe to that "events" collection and get realtime updates of it.
This work great, but looks like overcomplicated. Is there any way to subscribe from my backend to get all updates of all documents of firestore? Ideal solution is to subscribe to updates, as it done in Cloud Functions: https://firebase.google.com/docs/functions/firestore-events?authuser=0
The client and server SDKs don't have this capability. Cloud Functions is really your only way to get notified of changes in Firestore that match a wildcard pattern.

Vuex state in sync with Firebase

I follow some guidelines to have my Vue.js state in sync with Firebase. I have set up references to Firebase and getters, mutations and actions in vue in a separate folder store. It seems to work when I update the states without Firebase connections (local) and it also works when I update Firebase from other components only using the Firebasereference and push - then the sync seems to work. My question is if I should update the state throw "action / mutation" and the mutation will do a push to the state array and in som magic way the Firebase will update which not happens in my case.
So - how to update? From the component using the reference, for example dbOrdersRef.push(order) or with a call to the store with for example this.$store.dispatch('setOrder', order) which don't updates Firebase (but other local variables updates).
I think scheme should be like this:
You should subscribe on firebase updates somehow (I'm not familiar with firebase but I'm sure that there should be some mechanism for that) and when updates come from firebase - you should mutate your store by dispatching some actions, to keep you store in sync with firebase.
Ideally, your app should work with your store only. Store should hide such implementation details as firebase usage. If tomorrow you will switch from firebase to something else, you shouldn't rewrite your components which work with the store. They still will work with the store and with the same actions.
When you update something in your store you need to update firebase as well. I think you can do it right in your actions, it should be fine. In that way, you can be sure that all changes which will appear in your store, will be in firebase. E.g. you call someAction which actually do some firebase manipulation. If you subscribed on firebase changes you won't even do something else in that action, except sending some command for firebase, because your subscription will update your store. Or you can mutate the store immediately (aka optimistic update), then wait for response from firebase, and then decide leave that update or call some mutation to rollback (however here you should be very careful because of subscription on firebase changes).
Or, alternatively, you can write some plugin for your store, which will send updates to firebase only when some change in your store has been done. In that case, updates from your app firstly will appear locally in your store, then your plugin will send them to firebase (maybe such plugin even already exist, idk).
I'm not an expert in firebase, but tried to share some thoughts about how it should work in general. Hope this helps.
Oh, back to your question:
dbOrdersRef.push(order) or with a call to the store with for example this.$store.dispatch('setOrder', order) which don't updates Firebase
I think you shouldn't use firebase in components at all and should use your store instead. So I'd rather advice to use the second option. But you should implement firebase updates by your own, there are no magic updates from store to firebase by default (at least if you aren't using some plugin with that magic).

How to reload Algolia cache on CRUD operations?

Newbie here.
In Angular 5 application with instantsearch.js library, how do I reload Algolia cache from my model on CRUD operations? I am using Cloud Firestore as my database and I have a cloud function to sync the data with Algolia.
Currently, I have to refresh the browser for changes to take effect.
You should have a request sent to your frontends with for example websockets, when it gets a "new data" event like that, you should call search.refresh().
whateverListenerYouHave.on('data', () => search.refresh());
See also the docs, and some relevant issues: instantsearch.js#2670 and instantsearch.js#1050
In the context of Angular InstantSearch, you'll need to make a connector to have access to the search (instance of InstantSearch.js)

Resources