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.
Related
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.
I have more then 1500 users in roomdb. I want to sort users and also filter them with provided text. (User object have firstname, lastname, image(base64),nickname)
my question is: what is best way and fast way of doing so in Ionic?
Getting data from android roomdb with sorting and then loop over it to filter users in java. Then send result with JSArray to angular. ---OR---
Get all users once from roomdb, send to angular and now sorting them or filtering them in typescript, whenever user change sorting
(in first type I have to query every time to roomdb whenever sorting is changed or search text is changed but in second type i don't, as I have already all the Users object. But Second type could block UI as looping might take some time)
I think that you need to think in terms of space more than in terms of CPU.
Sorting 1500 users is not that much nowadays but loading 1500 base64 images can be huge for a smartphone or a navigator.
In database, it's often a good practice to filter soon. And it's probably the way to follow for your problem, the third solution is to filter through SQL so before Typescript and before Java.
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.
I'm developing a feature in my app to help users find friends who are registered and are in the contact list on the phone. Something like what instagram does here:
Does firebase have any way to synchronize and compare contacts? I think that comparing each phone contact with each database contact will not be very efficient in terms of performance.
Does firebase have any way to synchronize and compare contacts?
It does not. You should create your own system for that.
I think that comparing each phone contact with each database contact will not be very efficient in terms of performance.
Is not. In fact, is quite simple and efficient since Firebase SDK provides a method that can help you simply verify if a user exist or not in the database, this method is called exists().
For more informations, please also see my answer from this post.
I understand that one cannot do aggregation queries on firebase to compute statistics and/or return bucketed data similar to a relational db. I wondered if denormalising data could some how replicate aggregation?
I have the following specific problem:
I have a set of data with id, subject, score, author, date, tags, locations.
I would like to bucket the data in each of these dimensions according to some "similarity" rules e.g. all data on the same day bucketed together, all data located within 10 metres etc., each bucket showing me how many pieces of data in that bucket and the average score.
Once I choose a bucket, the underlying ids are retrieved.
Given a set of retrieved Ids, I download the data or go back to step 1 to refine using these ids.
I have gone through the Android documentation but cannot work out a way of doing this. Is something like this possible in Firebase? Is it possible via denormalisation or by uploading server code?
I am loathe to give up Firebase as it is so easy and simple to use but aggregation is a core part of my app so hope it is...
Thanks,
Riz
Edit: Edited to make problem clearer.