I built my Firebase database as flat as possible.
This is my structure: https://stackoverflow.com/a/40115527/3669981
with a little adjustment: Instead of role values in my projectsRoles node I'm using the role keys assigned to the /roles node (So I can add and edit roles easier).
The pain starts when I need to make 1 + (numUsers*2) Calls in order to get a project member list, assuming I already have the project ID.
Call to projectsRoles/$projectID to get all user IDS of the current project.
Loop each USER ID+Role ID received:
Get the role name by roles/$roleID
get user information by users/$userID
That means if a project will have 30 members, the app will make 61 calls to firebase database.
My question is: Although the number of calls is high, the data received each call is minimal. I followed the instruction to make is as flat as possible, But is it common to make so much calls to firebase?
Related
How to retrieve child nodes data and update values in firebase:
As I want to make an API in which I create parameters to pass values by it.
Like example I have one node in firebase name as users and under it has user amount is 10. I want to get that data of amount from users node and add some value with it like 10+5 will update in database as 15 in my firebase.
I tried to retrieve data from firebase by seeing youtube, but I'm unable to get what I want; I was only able to get the whole users node data at whole.
That sounds like a 2-step process:
Store the value as a number rather than as a string like you now have it.
Then use the atomic increment operation to increment it by 5.
I want to retrieve highest 10 scores from firebase . When i search stackoverflow i found some answers on here Firebase retrieve highest 100 score but i can not imagine how to implement them with REST API . My code is like this. I send request to end point and get response .
RestClient.Get<User>(databaseURL + getScoreText.text + ".json").Then(response =>
{
user = response;
UpdateScore();
});
Also for 2nd way, i can get all users' info by some json parser package and parse them and get the highest scores . But if my database gets bigger , i think i ll have problems . I need a way like "orderby". Do you know any way to implement "orderby" method to my restclient code ?
Reading the firebase docs:
Filtered data is returned unordered: When using the REST API, the filtered results are returned in an undefined order since JSON interpreters don't enforce any ordering. If the order of your data is important you should sort the results in your application after they are returned from Firebase.
It seems like scaling is a real limitation of the realtime database.
Firestore can do this pretty easily if you want to switch.
If you're sticking with realtime DB, I would save a separate database-reference that only ever contains the top 10 scores.
So when a player gets a new score, they would only upload it to this reference if it's higher than the 10th top score. This would mean you would only have a DB reference containing 10 or less top scores, and scaling wouldn't be a problem. I'm not very familiar with realtime DB, but I'm sure you could write a security to rule to enforce this in a secure, server authoritative manner, at the very least a cloud function.
Am looking at the data structure in this post and want to know how you would go about getting the emails of users who belong to a certain group when they could belong to several groups and the GroupID stored against that user is the current group they are participating in?
Do you store the email addresses with the userid under the "members" or, instead, for each member of the group, get that user's email address from the "users" document userid (this would mean iterating through the group/members collection and doing a query for each user. Not very efficient).
Am used to SQL so this is all new to me.
You should have a single node for each user
/users/UID/emails/
/users/UID/emailunread/
/users/UID/settings/
/users/UID/details/
/users/UID/payments/
So you can simply do a subscription for a singular node path this.myDatasubscription = this.DB.list('users/' + this.uid).snapshotChanges() ensuring changes like new emails or account settings will detected and rolled out in real time back to the app, so your are using angular/ng or something similar client side then your variables {{this.email_list}} should update real time with no page changes.
Take a look at this one.
error: Property 'getChildren' does not exist on type 'DataSnapshot'
I have a question regarding authentication using Google Firebase.
For an app, I want to build an authentication similar to the one Slack uses: first, the user provides the input as to which group they want to log in to. If there exists a group with the same name as provided in the input, the user is then taken to a login/signup screen.
I've thought about storing users in the realtime database as follows, but I think there must be a better way to do this (since I don't think I can use the firebase authentication in this case):
groups: {
"some_group_name": {
"users": [
"user1": {
.. user 1 information
},
"user2": {
.. user 2 information
}
],
"group_details": {
"name": ..,
"someGroupDetail": ..
}
},
"some_other_group_name": {
...
}
}
I haven't realized if there is an obvious answer yet, so I'm open to suggestions. How would you suggest I tackle this?
Thanks
PS: I'm building the application using Nativescript and Angular, and (so far) there is no server or database involved other than Firebase.
Another suggestion that might work, is by using Firebase Auth Custom Claims. That way, you only need to store the group ID and group name in your realtime database, without worrying to keep changing the database each time user is added or removed.
This is one way you can do it:
Store database exactly like you have it, with it's group ID and name.
In your backend script (I recommend Cloud Function), each time a User is registering themselves, add custom claims in your user: Specifying what group is the User belong to.
Every time user authenticate, retrieve the group ID from custom claims. And there you get it!
Note: be careful not to put too much information in your custom claims as it cannot exceed 1000 bytes.
Read more about it here: https://firebase.google.com/docs/auth/admin/custom-claims
I would suggest you to implement Root-level collections.
Which is to create collections at the root level of your database to organize disparate data sets(as shown in the image below).
Advantages: As your lists grow, the size of the parent document doesn't change. You also get full query capabilities on
subcollections.
Possible use case: In the same chat app, for example, you
might create collections of users or messages within chat room
documents
Based on the reference from the firebase cloud firestore
Choose a data structure tutorial (I know you are using Realtime database but structuring the database is the same since both are using the NoSQL Schema)
For your case:
Make 2 Collections: Users, Groups
Users: User info is stored in the form of document
Groups: In the Groups Collection, here comes the tricky part, you can either store all groups subcollection under 1 document or split into multiple documents (based on your preference)
In the group-subcollection, you can now store your group info as well as the user assigned where you can store user assigned in the form of array, therefore whenever a user access the group, query the user assigned first, if yes, then allow (assuming users can view all group)
You do the thinking now
I am building a chat engine using firebase in unity. I want to differentiate between the existing data and all the new data that gets added into the database. There is method once in web sdk of firebase which helps in differentiating between old and new data, is anyone aware if we have something similar on unity
There is no direct way to do this, one way that is a workaround is to add a timestamp value in all the entries maintained in the database and each time one subscribes for the new data we make use of the OrderByValue|OrderByKey and StartAt to do the same.
In the beginning value for StartAt will be 0 but post that whenever a child gets added we can update the StartAt value to that so that the next time client subscribes for the childAdded, it will only receive data post the last child.