Firebase's KeepSynced and persistenceEnabled - firebase

I'm using Firebase's KeepSynced and persistenceEnabled but i don't understand it completely.
I have 2 questions -
What do this functions do exactly? I understand that they connected to cache and offline logic but why do i need them both?
I have a list of categories, and after the user choose a category i show a list of all groups related to this category.
I'm using firebase database.
How can i create cache for the groups, but at the same time refresh the group list after the user choose category? Is it possible to only refresh the data that is missing from the cache?
thanks for the help.

Related

Querying on Firebase or on the client

Basically I have a set a of data on my website and on I have some checkboxes where the user can check to filter the data. The data will be 40 items per page. Should I query my data in firebase or when I get the data back from firebase. The reason I'm asking is because the user can check and uncheck the checkboxes which means every time the users the users does that I'm getting charged, since firebase charges by use by at the end I want to make sure I follow the best practices.
The queries will have OR. I know in firebase there's not such a thing as an OR when querying but I found a workaround
https://medium.com/google-developer-experts/performing-or-queries-in-firebase-cloud-firestore-for-javascript-with-rxjs-c361671b201e

Checking for New Entries in Firestore - Local Storage

So I have a Firestore database where i have all my posts in, I push them on page load into the store so I can have a fast navigation and only need to fetch once.
What I wanna do now is to use a persisted state so i dont need to refetch it if the user opens a new window or F5(reloads) the page.
The problem is im not sure how to check if new Posts are in the Firestore without querying all posts and I havent found any methods to do it in a healthy and Read efficient way.
There's no super easy way around it - at the end you have some data, and the server has another, you need to check for differences.
If you're only trying to figure out if there are new posts on the backend, which are not loaded on your frontend, then just get the date on your last post, and then ask Firebase for all posts after this date :)
Of course if you don't have posts, ask for everything.
Keep in mind you need to manually check if posts are deleted ;)
Realtime updates with the onSnapshot method can be used to keep local data in sync with the server. If you initially load it into vuex then subsequent changes on server side will be reflected automatically.
https://firebase.google.com/docs/firestore/query-data/listen
To share one set of data across tabs/windows you could look at something like this
https://github.com/xanf/vuex-shared-mutations

Can Firebase Realtime Database effectively loop through billions of posts and retrieve them by the users that posted them?

I am developing an iOS app with Firebase Realtime Database. The app will potentially have billions of posts with a number of images and data that needs to be retrieved based on the people a specific user follows (something like Instagram).
I understand that the best practice in Firebase is to structure data as flat as possible which would mean having a "Posts" node with potentially billion of entries, which I would then filter by a kind of 'posted_by' parameter. This begs two questions:
1) Will I be able to retrieve said posts with a query that returns posts by any of the users I follow? (By passing something like an array of the users I follow)
2) Will Firebase be effective enough to loop through potentially billions of posts to find the ones that match my criteria, or is there otherwise a better way to structure data so as to make the app as optimal as possible?
Thanks in advance for the answers.
Billions of entries are no problem.
You should check if Firebase is the most cost efficient solution if you have huge volume of data.
1) Firebase can do that, but you probably don't want the user to wait for all entries (when there are a lot for a single user), but instead request them "page" by "page" and only request more pages on demand when the user scrolls up/down.
2) If you ensure you have an index on the user id, then it doesn't have to go through each one individually. Searching by index is efficient.

Firebase social media app: saving groups of users

In a Firebase social-media-esque app, here is how I'm storing groups along with its members:
Here, I have a reciprocating relationship in terms of memberships of groups. A group knows all of the users that are a part of it in group-users and vise-versa—a user knows all of the groups it's in via user-groups. The reason I thought to do this is it seems to be quick for a user to access all of its groups, and likewise it seems to be quick for a group to access all of its users. However, having this reciprocating data is costly in terms of space. My other option would be to keep just the user-groups node, and to retrieve all the members of a single group I would need to query that node by group ID. This option seems slower but would take less space in the database. Which option is more advised? Thanks.
The best data model always depends on the use-cases of your app. If you need access to both the groups-for-a-user and the users-for-a-group, the cheapest way to do so is to store both.
See:
Many to Many relationship in Firebase
the answer to this question in a video
this article about NoSQL data modeling
the Firebase video series Firebase for SQL developers

How can Firebase nodes be structured to restrict user access and allow admin to pull report data?

Context: I am putting together a time tracking application using Firebase as my backend. My current node structure has Time Entries and Clients at the root like so:
Time Entry
Entry ID
UserID
clientID, hours, date, description, etc
Clients
ClientID
name, projects, etc
This structure works fine if I'm just adding and pulling time entries based on the user, but I want to start putting together reports on a per client basis. Currently, this means making a separate HTTP request for each user and then filtering by the clientID to get at the data.
The rule structure for Firebase grants access to all child nodes once access is given to the parent node, so one big list doesn't work as it can't restrict users from seeing or editing each other's entries.
Question: Is there a way to structure the nodes that would allow for restricting users to only managing their own time entries, as well as allow for one query to pull all entries tied to a client?
** The only solution I could come up with was duplicating the entries into a single node used just for reporting purposes, but this doesn't seem like a sustainable option
#AL. your answer was what I went up going with after scouring the docs across the web. Duplicating the data is the best route to take.
The new Firestore beta seems to provided some workarounds to this.
The way that I would do this is with Cloud Firestore.
Create a root collection clients and a document for each client. This partitions the data into easily manageable chunks, so that a client admin can see all data for their company.
Within the client document, create a sub-collection called timeEntries. When a user writes to this, they must include a userId field (you can enforce this in the rules) which is equal to request.auth.uid
https://firebase.google.com/docs/firestore/security/rules-conditions#data_validation
You can now create read rules which allow an admin to query any document in the timeEntries sub-collection, but an individual user must query with userId = request.auth.uid in order to only return the entries that they have created.
https://firebase.google.com/docs/firestore/security/rules-conditions#security_rules_and_query_results
Within your users/{uid} collection or clients/{clientId} collection, you can easily create a flag to identify admin users and check this when reading data.
https://firebase.google.com/docs/firestore/security/rules-conditions#access_other_documents

Resources