In my chat application, I store the participants of a chat as their UIDs in a Map so I can so I can do queries like this:
.whereEqualTo("participantUIDs.$currentUserUid", true)
.whereEqualTo("participantUIDs.$partnerUid", true)
The problem is when I try to use this with orderBy
.whereEqualTo("participantUIDs.$currentUserUid", true)
.orderBy("lastMessageSentTimestamp")
I have to create a custom index. But this index will contain that specific user UID and I can't create an index for every user in my app. How can I circumvent this problem?
You can order the documents on the client after an unordered query. This should not be very taxing on the client app when the number of documents is less than 10,000.
Regarding:
I can't create an index for every user in my app.
That's definitely not an option, as there are some limitations when it comes to Cloud Firestore indexes:
https://firebase.google.com/docs/firestore/quotas#indexes
However, even if you manage to stay below these limits, that's not an option to manually create an index for each and every user that joins your app.
In my opinion, for your particular use-case, you should consider augmenting your data structure to allow a reverse lookup. Meaning that you should create a participantUIDs collection where you should keep the lists for each user. This technique is called denormalization and is a common practice when it comes to NoSQL databases like Cloud Firestore or Firebase Realtime Database.
But remember, there is "no perfect database structure":
What is the correct way to structure this kind of data in Firestore?
It's a little old, but I think this video might also help:
https://www.youtube.com/watch?v=u3KwKQddPoo
More info regarding why you need an index:
Why does this firestore query require an index?
P.S. You can also rely on Firebase Realtime Database when Cloud Firestore may become a little expensive. Both work really well together.
Info:
Array or Subcollection for storing events user uploaded
Related
I want to make a large e-commerce app. Here is the node and child number I want to use. I want to make 500 nodes, each node has 1000 child and each child has 10 children like name, price, type, location, phone number, description, date, etc. And my app has daily users are 1000.
Can I use the Realtime Database for this? Users can show data without problems?
None of these sound like they go beyond the documented limits of Firebase's Realtime Database.
As usual with NoSQL database, performance will depend more on how you implement things than on the database itself though, so be sure to read the documentation on structuring data, how to secure data access and watch David's classic video series on Firebase for SQL developers.
if your data is large then we using paging in our recycler view. we integrate paging in real time to fast your application response. Real time support start position and also limit same as sql.
check this link:
Firebase android pagination
I am using firebase Cloud Firestore for my Android and iOS apps. I am stuck with how to structure my database.
Basically I have an "organization" collection that contains many users, and for every user, I want to save attendance time and leave time for every day.
The problem is I want to generate reports that allow me to get every day-attendance for each user, single-day attendance for all users, and all days attendance for all users.
so I tried this: inside the user I would have an "attendance" collection then each document is Unix timestamp of that day (to make sure that it's unique). then save fields like attend_time and leave_time...etc. the path is like that "/organization/android/users/3PRs42gRFzZQhLKcUhpf4wPMRV43/attendance/1590271200"
then I needed to get attendance for a single day for all users, so I did this: now I have another path "/organization/android/attendance" and inside the attendance, I store the Unix timestamp of the day, then the user ID then his attendance. and now I am saving attendance twice.
but I still can't get attendance for all days for all users!
this would be easy in Relational Database like SQL. any idea how to do it in firebase?
If you want to track attendance across all users, you're looking for a collection group query. This allows you to query documents from all collections named attendance.
Since a query in Firestore can only see data in the collection(s) it queries, you may have to duplicate some data from parent collections (your users and organizations) into each attendance document to allow the query. This type of data duplication is quite normal in NoSQL databases too.
Finally: if you need to perform many ad-hoc queries, you might want to consider using a database for those that is more suited to that use-case. For example, it is quite common to use Firestore to handle the direct-to-client interactions that require scaling to massive number of users, but then use BigQuery for the ad-hoc querying of that data. There is even a Firebase Extension that automatically exports to BigQuery to make this easier.
I need to perform two different queries in my app.
Display a global leaderboard (rank all users based on points)
Display a leaderboard only among friends of the currently logged-in user.
Currently, I have structured my database as follows.
Users (collection):
user_id (document):
...
points: number
...
Friends (sub-collection):
user_id (document):
name: string
points: number
This approach works for populating the global leaderboard as it's just:
db.collection("Users")
.orderBy("points", Query.Direction.DESCENDING)
.limit(10)
.get()
Displaying a leaderboard among friends of a user also works in this case, but updating points of a user becomes an expensive operation because of multiple duplication.
Is there a way to structure my database so I can efficiently query and update my users collection?
I think what you're doing now is probably the best way to go. Data duplication is normal for NoSQL type databases, and it's expected that you'll do multiple updates to keep everything in sync if something changes. That's totally normal.
The alternative is to keep all relevant data in a single collection somehow (don't use a subcollection to store friends), but then you'll end up with a different problem of eventually exceeding the capacity of the document that contains all the data for each user.
The bottom line here is that NoSQL databases like Firestore give you better scalability and faster queries at massive scale, at the expense of less flexible querying and more work keeping duplicated data up to date. If you would prefer more flexible querying and easier updates, then Firestore might not be the best database for your application.
I am struggling with creating Android database for my app. Below is the picture of the data I need to save/store based on the location.
On Device: I need to store sensor which comes at a frequency of 100Hz. User is going to use the app app for few hours which means there is going to be a lot of sensor data. If user is going to use the app multiple times (multiple session) after short breaks then I need to store data sensor data perssion wise on device.
What I was thinking: Create SQlite database and create a table and add column dynamically and add sensor data to that column. Each column is session. col 1 = session 1, col 2 = session 2 etc.
Is it bad to do like this then what you guys would suggest?
In cloud: Now, how should I go about creating database if this data is going to get stored on cloud (GoogleCloudPlatform specifically) per user per session wise sensor data.
Any suggestion is welcomed. Please don't mark it as broad question because I am looking for efficient method to achieve this.
Refer the image below for further explanation or ask me for further explanation.
I prefer to youse RoomDB as per your requirement and consider the facts. Because Room provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.
Apps that handle non-trivial amounts of structured data can benefit greatly from persisting that data locally. The most common use case is to cache relevant pieces of data. That way, when the device cannot access the network, the user can still browse that content while they are offline. Any user-initiated content changes are then synced to the server after the device is back online.
Also, I prefer to use firebase realtime DB along with room for better efficiency and reliability. If you are using roomDb and firebase for cloud storage you can use a single entity for both firebase and roomDb. It will also help you write less code and better reliability.
Because Room takes care of these concerns for you, I highly recommend using Room instead of SQLite.
For reference, Please go through this link Save data in a local database using Room
I have a database in Firestore that is available for all my users. This way updates made by me to this database is instant updated for my users.
My challenge is that my users can edit some of the data in the database - user preferred values. These changes can of course not be written to the public database, but must either be written to a local SQLite-database on the phone or somehow written to each users private collection of documents in firestore.
A SQLite solution means that each time a document from Firestore is displayed, I need to read the local SQLite database to check for changes.
Using private collection of documents in Firestore means that I have to read two documents for each item that I want to display.
I struggle to find the "perfect" solution for this situation.
What is the best approach? Is there a solution I haven't thought of?
I believe the best approach is Firestore Security Rules.
Any data for a user should go in a special document: /users/userId
Set up the firestore rules so that this document is only writable by the user with ID === userId. You can make the document readable by all if you need or limit it to only the user who created it.