Firestore Database Structuring - android

I am building a social app that lets users add posts based on the country code. For main feed, I will fetch posts of every country posts based on timestamp. For example, if you are in Turkey, only posts within Turkey will show up in your feed. There is no follower/ following system.
Should I store all posts in one posts collection with the country code field? Or it is more flexible to group them as posts/countryCode/posts. I just don't know if firestore is powerful enough to query all posts for specific country code and timestamp.
What is the best approach for flexibility and pricing?

For only what you're describing here, it actually doesn't matter at all what you choose.
Pricing is based on the number of documents read in a query. That's not going to change in either case.
If all you want to do is query by country code, it doesn't matter if you put everything in one collection, or use subcollections with a collection group query. As long as the country code is a field in the document, either way, you will be able to filter for only that code.
Choose whatever one you are more comfortable with.

Related

Running a nested query in Cloud Firebase?

I'm messing around with Cloud Firestore. Trying to decide whether I should use it for my next project.
I would like to make a nested query, but all the tutorials and examples I found in the official documentation only query objects which are 2 levels deep and most of the time direct key/id calling.
I need something which is I believe called "nested query" I may be wrong on that one though, maybe it is not the correct phrase for such a thing in NoSQL which I just started to learn.
This is a skeleton/pilot app for a game where users can create characters. and I would like to query whether a character's name is already taken or not.
Here is my simple DB structure:
The main collection is named "users"
In "users" I have user documents.
In each user document, I have a collection named "characters"
In "characters" I have character documents.
In each character document there are two fields, name and level.
I tried it various ways with queries and the closest thing I could get was iterating through the whole thing which I believe is not the perfect solution.
Can somebody please help me to write an efficient nested query whether "Example Name" is already an existing character in the DB and tell me what is the correct way when you want to write like "infinitely deep" nested queries?
If each user document contains a sub-collection that has the same ("characters") name, then I think you are looking for a collection group query. So a query should look like this:
val queryByName = db.collectionGroup("characters").whereEqualTo("name", "Adam");
Don't also forget to create an index.
Besides that, Firestore is as fast as it is at level 1 is also at level 100. So no worries.

Is there a way to search for a document in several collections without having to read them all? Firestore

I have a set of collections in Firestore that each has n different documents, each one with its particularity, in my application I have a menu that the user can search for a specific document and I must search for that document.
However, the problem lies in this case, I do not know when searching for which collection to look for the document in, so far I am searching all collections to find the document the user wants in himself, I wonder if there is any way to search for a document without knowing exactly what collection it is in but in a way that I don't have to go through the database completely.
Currently I do something like this:
Search Lot 01 collection:
...>search returned the document: then cancel the searches.
>search did not return the document, so proceed with the search in Lot 02 ...
and so on until you find the document...
In SQL I would basically have one of these fields as the primary key and search for it, but Firestore is NoSQL
if there is any way to search for a document without knowing exactly what collection it is in
That's not possible. All Firestore queries require the name of a single collection (or collection group, where all the subcollections have the same name).
With Firestore, if you want a set of documents to be searchable, then they have to be in a collection with a name that you know ahead of time. You might have to duplicate data into this known collection to solve this particular problem. Or, find a database that does allow universal searching, like some full text search engines allow.

Firestore document sharing without scanning entire collection

I am learning my basics for Firestore and trying to build an app which allows user1 to share a document with user2/3/4 etc.
For billing purposes, every query which results in a document read counts towards the cost. So, I do not want to follow the approach of adding the user2/3/4 etc emails to a 'sharedWith' variable to type: array or map type structure as I believe every user will then have to scan the entire collection and pick the documents where their email appears.
Is there any other approach to this where user1 can programmatically give access to user2/3/4 of one specific document?
For billing purposes, every query which results in a document read counts towards the cost.
That's correct and according to the official documentation regarding Cloud Firestore billing:
There is a minimum charge of one document read for each query that you perform, even if the query returns no results.
So you're also charged with one document read, even if your query does not return any results.
I believe every user will then have to scan the entire collection and pick the documents where there email appears.
That's also correct. So let's assume the email address that you are looking for exist in a document that is appart of 10k collection of documents. So if you query the database only for that particular document, you'll be charged with only one document read and not for those 10k. So you are charged according to the number of items you get back and not to the number of items your request them from. And this is available for the first request, when you get the data from the Firebase servers. If in the meanwhile nothing has changed, second time you get the data from the cache since Firestore has the offline persistence enabled by default. Which means you aren't charged for any other document reads.
Is there any other approach to this where user1 can programatically give access to user2/3/4 of one specific document?
Without writing the data to database, there is not. So you should add the ids or email addresses to the desired documents and perfom a query according to it.

Firebase search for all objects that contain a value in a list

I am attempting to search for all users who are a part of a given club/organization. I would have both the clubsOrgsId and clubsOrgsName. In the list of users these two data points are in an object named by the clubsOrgsId in a list called clubsOrgs, as seen below. Is this possible to do with a Firebase query; I would rather not run the search locally.
This app is being written in Kotlin but an answer is appreciated regardless of programming language.
Your current data structure allows your to efficiently find the club orgs for a given user. It does not allow you to efficiently find the users for a given club org. If you want that, consider adding an inverted data structure to allow it:
CLUBORGS
$cluborgid
users
$uid: true
With this additional structure in place, the lookups are super easy.
Also see:
Firebase query if child of child contains a value
Firebase Query Double Nested
Many to Many relationship in Firebase

Firebase Query: equalTo on a list

We are building an android app that needs to synchronize phone contacts with people already registered on the app. We are using firebase
To do this, we'd like to retrieve a list of existing users based on their phone numbers.
I have managed to retrieve users based on their phone number with ref.orderByChild("phone").equalTo($phoneNumber)
But I am wondering if there is a way of passing a list of phone numbers, instead of querying for each phone number one at a time ?
Something like this:
ref.orderByChild("phone").isIn([phone1, phone2, phone3])
I am just beginning to learn Firebase but I love the concept :)
Thanks a lot for your answers!
Firebase doesn't have or or in operators on its queries.
The closest you can come with with the startAt and endAt functions, to select a range. But that doesn't work for your use-case.
Normally when people are asking for this type of operation, there is a relation between all the pieces that they're trying to combine in a query. For example in your case, the use-case is likely something like: "get the name for all contacts in the user's address book".
In such a situation there are a few options:
monitor each contact with a separate query
embed the necessary metadata for each contact into the user's address book
Option 2 is the cheapest way to get the information, because you only need to read the address book. But it comes at the cost of data duplication, which more relationally trained developers are unused to. See this answer for a coughgreatcough example of such denormalization: Firebase data structure and url
Option 1 is not nearly as expensive as you may expect, since Firebase will open a socket connection only once and then perform all additional queries over that same connection.

Categories

Resources