Collect all 'name'-fields from Google Firebase Realtime Database - firebase

I have a Google Firebase Realtime Database with the following structure:
project
|
- users
|
- uid_1
|
- name
- age
- ...
|
- uid_2
|
- name
- age
- ...
I'm new with Google Firebase. I can read all db-fields from a specific 'uid'. But how can I collect all names from all unsers? I want to make an file-uploader and to assing the file to an existing user, I want to use a dropdown-menu to select the user.

With the way you have this data structured, you're going to have to write code to query everything under "users", iterate the children, and pull the names out of each child.
Realtime Database doesn't offer any sort of SQL-like projection type query that will get you just the vales of certain children. Or to put it another way, you can't do anything like "select name from users". If getting only the name is a common operation for you, you will need to duplicate only the names into another parent node, and query that new node instead.

The Firebase Admin SDK allows retrieving the entire list of users in batches. But max result is 1000.
Or you can denormalizing your data.

Related

Firebase Firestore Flutter run multiple queries vs. denormalize data

I'm currently working on a dating app and I'm trying to find the best approach showing clients recommendations for other user profiles on my home screen based on their behavior.
So in my case they have to match certain criterias (gender, age) and I have to make sure that the client didn't like them yet. Matching criterias works fine, but filtering out all the profiles which where already liked seems to be quite hard.
I've already learned that denormalizing data is a good approach keeping queries simple. But for my case it doesn't make sense to me. I don't see a way accomplishinging this without duplicating millions of data.
This is my firestore structure:
users - documentId
- userName
- firstName
- lastName
- city
profiles - documentId
- userId
- firstName
- lastName
- city
- gender
- subcollection likes
- documentId
- userId
- timestamp
This is how I get profiles (minified example):
CollectionReference profileRef = _db.collection('profiles');
// Query definition
final ref = profileRef
.where('criteria', arrayContainsAny: criteria)
.limit(5);
Thinking of a solution
I thought about getting the profiles first like in the above query, save the Ids to a list and run a second query by finding out if the user already liked the profile. It would cost me 10 reads and the fact not having all the data from a single query.
I already read in the docs and watched firebase youtube channel, but I didn't find any benchmarks/experience/advices on running multiple queries or furthermore when to do what in the special use case.
I would love to have some input from you guys.
I think another possible solution could be by changing a bit the Firestore structure.
For example you could store the usersId liked by that profile in an array inside the documentId and then you can query to match the certain criterias and also that in the array does not exist that userId.

Organizing a Cloud Firestore database

I can't manage to determine what is the better way of organizing my database for my app :
My users can create items identified by a unique ID.
The queries I need :
- Query 1: Get all the items created by a user
- Query 2 : From the UID of an item, get its creator
My database is organized as following :
Users database
user1 : {
item1_uid,
item2_uid
},
user2 : {
item3_uid
}
Items database
item1_uid : {
title,
description
},
item2_uid : {
title,
description
},
item3_uid : {
title,
description
}
For the query 2, its quite simple but for the query 2, I need to parse all the users database and list all the items Id to see if there is the one I am looking for. It works right now but I'm afraid that it will slow the request time as the database grows.
Should I add in the items data a row with the user id ? If yes the query will be simpler but I heard that I am not supposed to have twice the same data in the database because it can lead to conflicts when adding or removing items.
Should I add in the items data a row with the user id ?
Yes, this is a very common approach in the NoSQL world and is called denormalization. Denormalization is described, in this "famous" post about NoSQL data modeling, as "copying of the same data into multiple documents in order to simplify/optimize query processing or to fit the user’s data into a particular data model". In other words, the main driver of your data model design is the queries you plan to execute.
More concretely you could have an extra field in your item documents, which contain the ID of the creator. You could even have another one with, e.g., the name of the creator: This way, in one query, you can display the items and their creators.
Now, for maintaining these different documents in sync (for example, if you change the name of one user, you want it to be updated in the corresponding items), you can either use a Batched Write to modify several documents in one atomic operation, or rely on one or more Cloud Functions that would detect the changes of the user documents and reflect them in the item documents.

Flutter Profile Matching App - Cloud Firestore Data Modeling | How to Query to avoid unnecessary reads for already swiped UID´s

I tried my best with the search function and not really getting the results I´m searching for.
At the moment I try to replicate a functionality for swiping profiles on a card stack. The profiles are loaded over a Firebase Firestore backend. The problem is, due to the geoFireStore query, I get with every load within a specific radius a whole bunch of documents and I would like to reduce the read amount directly in the query.
So what I'm trying to achieve is, that when I swiped a profile once (left or right) I never want to read it in the query again. In addition, to save reads, I don't want to do this client sided, it should be done in the query directly.
Firestore JSON structure at the moment:
Users (collection)
UIDs [documents]
name
active
match {map}
If the match map doesn't contain the own UID (if exist is null) then read in query, else when own UID exist in other user profile under the map match (boolean: true or false for liked or disliked) then don't show as query result.
My stream is built this way:
return geo
.collection(
collectionRef:
friendrCollection.where("active", isEqualTo: true).where("match.$uid", isNull: true))
.within(
center: geoFirePoint,
radius: suchRadius,
field: 'position',
strictMode: false)
.map(_friendrsGPSListFromSnapshot);
}
I am working on this for 3 weeks now and not getting the results I want :D
-Should I stay with firestore or better the real-time-database?
-How do I need to structure the data to get a "except" query working?
Right now it is like:
Collection: Users --> Documents: UIDs --> Match{ownUID}
Thanks in advance
Andreas :)
I still not managed to find a proper solution to reduce the number of unnecessary profile reads inside the firestore query.
Has anyone an idea to handle this part?
The only way I found was to lookup existing matches on the client side (extra firestore collection), but that means that I always have to load the whole bundle of profiles and throwing them away afterward :(
Thank you!
Andreas

Firebase Rules for Unique Child Name

Assuming a simple data structure:
-root
-uid
name:string
-uid2
name:string
Is there a way on firebase side(server) to restrict the unique name?
I've seen some solutions like to store names on another node. The problem would be the store action is actually carried out on client side. It is still easy for a registered user to bypass the checking.
Thanks!

can you create indexes on embedded objects in dynamodb

Coming from a mongodb background, I'd like to set up a document with an embedded collection.
For instance if I have a profile object
Profile
name : string
followers : [
name: string
]
such that it has an embedded collection of followers.
Is there a way that I can create an index on Profile so that I can query for all profiles where Profile.Followers includes myUsername?
In short I can query for profiles I'm following from a dynamoDB table?
In mongo I can easily do this by setting up an index on Profile.followers and doing an $in query. Is there something similar for dynamodb?
This documentation suggests there is nothing like an in clause
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html
Currently DynamoDB does not support indices for non scalar types (i.e. Set, List, or Map data types - see here: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html). If you have a separate users table, you can keep track of all profiles you are following in a Set/List attribute.

Resources