If I want to push a data base node in the real time database called (messages):
It have this structure:
messages
|
current_id
|
user_id
|
push_id1
|
push_id2
Now if I want to push into messages/current_id/user_id
Then does it matter
if I do this:
my_ref= FirebaseDatabase.getInstance().getReference().child("messages").child(current_id).child(user_id).push();
or this:
my_ref= FirebaseDatabase.getInstance().getReference().push();
If yes. Then how does it differ?
EDIT
So I will explain how I used my code according to franks suggestion
so I got the push id from the first snippet frank suggested:
String push_id= my_ref.getkey();
then I did this to multi update 2 locations
first location: messages/ current_id/ user_id
second location: messages/ user_id/ current_id
Map message_map=new HashMap();
message_map.put("messages/current_id/user_id/"+ push_id, "some value");
Map message_map_2=new HashMap();
message_map_2.put("messages/user_id/current_id" + push_id, "some_value");
root_ref.updateChildren(message_map);
root_ref.updateChildren(message_map_2);
I noticed that at location 2 push ids are not sorted normally (not sorted in order).
But at location 1 they are sorted normally.
Dont ask me why I split the multipath update.....its for security rules reasons.
Calling ref.push() on any DatabaseReference essentially does two things:
Create a new ID that is statistically guaranteed to be unique, based on the current timestamp of the client and a lot of randomness to make it unique.
Create a new DatabaseReference point to ref.child(newId).
This
my_ref= FirebaseDatabase.getInstance().getReference().child("messages").child(current_id).child(user_id).push();
Creates a reference to a new location under /messages/$current_id/$user_id.
This:
my_ref= FirebaseDatabase.getInstance().getReference().push();
Creates a reference to a new location under the root.
Since you want a new child under /messages/$current_id/$user_id, you need the first snippet.
Note that neither snippet actually writes any data yet, which requires you to call setValue(...) or updateChildren(...).
Related
When a new user signs up, there should be a property named userNo. which should be increased by 1 in each document, so that it would be easy to pick random users from db using that userNo. Basically, like each document holds a User number similar to Uid but not like Afhghdfh4hk545, it should be like userNo.23 and so one. If a new user signs up its userNo. should be 24. Here is what I have tried.
Stream dummy =
await FirebaseFirestore.instance.collection('users').snapshots();
var doclength = await dummy.length;
var userNo = (dummy == null || dummy == 0) ? 1 : doclength;
FirebaseFirestore.instance
.collection('users')
.doc(currentUser.uid)
.update({'userNo': userNo});
Alright, you'll need a "meta document" that has a field called something like "next_user_number".
Upon creating a new user, you check the number on that field and use it as the "UserNo" for the newest user.
And after that, you increase the "next_user_number" in the "meta document" by 1. (here you want to use FieldValue increment - search for "firestore increment" for how to do it.)
But... to be absolutely sure this will work even in cases when two users are signing up at the same time or other error-prone cases, make sure you use a "batch write".
A batch write means that both operations are done together, so both incrementing the "next_user_number" and creating the new user with the right "UserNo" number are going to be accurate. (search for "firesotre batch write" to learn more).
Okay, I solved it after drinking mugs of coffee. To all of the future visitors you can get the exact length of documents in that particular collection and then use then keyword and extract the value and store it in int variable. Then you can use extractedValue.size as the userNo.
I'm very new to firebase as this is my first project so any help is appreciated because this problem has taken quite a few hours of my time. I think the solution could be very simple but I'm failing to see it.
I would like to collect user-specific data upon every login to the app so it'd be something like this (in the real-time database):
-user-id{
-10:40:50:{
-location:"loation1",
-activity:"walking",
-batteryLevel:"90%"
}
-11:50:30:{
-location:"location2",
-activity:"running",
-battery-level:"80%"
}
}
I have tried to start by simply making different nodes (the timestamps) for every login before I go into more details with the children of these timestamps (location, activity and battery level).
I thought the code below would create something like this:
-user-id{
-10:40:50:"10:40:50"
-11:50:30:"11:50:30"
}
But instead I only get
-user-id{
-11:50:30:"11:50:30"
}
My problem is that every time the user logs in, the new timestamp overwrites the old one so user-id always has only one child node (the timestamp associated with the latest login).
This is the code I tried. PS: I have tried replacing ".setValue()" with ".push().setValue()" but the last timestamp always erases the previous one.
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference(firebaseAuth.getCurrentUser().getUid());
myRef.setValue( firebaseAuth.getCurrentUser().getUid());
String currentDateTime = DateFormat.getDateTimeInstance().format(new Date());
DatabaseReference usersRef = myRef.child(currentDateTime );
usersRef.setValue(currentDateTime);
The code above I've put it in the Oncreate of the activity "ProfileActivity.java" which is basically the activity the user is redirected to after he is correctly authenticated.
Thank you for your help.
This is a very silly mistake.
DatabaseReference myRef = database.getReference(firebaseAuth.getCurrentUser().getUid());
myRef.setValue( firebaseAuth.getCurrentUser().getUid());
These two lines of code always completely clear your node and set the value to your Uid.
If the node looked like this before
user123
- name:"peter"
- 10:40:50:"10:40:50"
it will now look like this
user123:"user123"
You set the complete content of the node to your Uid. If you just remove your myRef.setValue(...) statement, your problem will be solved.
I have a realtive simple Firebase database, in which i have 2 models. A ListModel and a UserModel. In my Lists, i'm using push() method to generate unique ids. Each unique id i want to be added as a key and "true" as it's value under Users/gmail#gmail,com/Lists.
When i add the first list, the database looks like this:
And everything works fine, but when i try to add another one, the database looks like this:
In Users/gmail#gmail,com/Lists, the first one is overwritten by the second insert. How can i add the specific id and the specific value, as a new item as shown below?
And this is my code:
final UserModel um = new UserModel();
um.setUserEmail("gmail#gmail,com");
userDatabaseReference.setValue(um);
ListModel lm = new ListModel();
lm.setListName(listName);
listKeyDatabaseReference = listDatabaseReference.push();
listKey = listKeyDatabaseReference.getKey();
listKeyDatabaseReference.setValue(lm);
listDatabaseReference.child(listKey).child("Users").child("gmail#gmail,com").setValue("true");
userDatabaseReference.child("gmail#gmail,com").child("Lists").child(listKey).setValue("true");
Thanks in advance!
Check the official doc:
For basic write operations, you can use setValue() to save data to a specified reference, replacing any existing data at that path.
Your problem is here:
userDatabaseReference.setValue(um);
In this way you are overriding all children in the userDatabaseReference path.
It means that the first record in Users/gmail#gmail,com/Lists is just deleted when you are adding the second one.
Before using the
userDatabaseReference.setValue(um);
you can check if the record exists.
If doesn't exist use the setValue to add the user-model with all its data.
If it exists, just skip this step and add the data in the lists path inside the same user.
In order to store all the states and districts with unique key value, I have written the following, but data is always overwritten.
Map<String, Object> dist = new HashMap<>();
dist.put(item.getDistrict().toLowerCase(), item.getDistrict());
ref.child("States")
.child(state.toLowerCase())
.child("Districts")
.setValue(dist, callback);
States
- andhrapradesh
-name: "Andhra Pradesh"
-Districts
- vizag
- name : Vizag
- eastgodavari
- name: East Godavari
How to push the data correctly for the first time. Next time I have to get all states at once, based on the states selection, I have to show the districts in UI.
Can anyone help me on this approach ?
You can give the node a unique key generated by firebase using the push method on any firebase database reference, but if you want to use your own key be sure that you use updateChildren method instead of setValue method
To update the existing districts, use updateChildren():
ref.child("States")
.child(state.toLowerCase())
.child("Districts")
.updateChildren(dist, callback);
I highly recommend reading the Firebase guide and reference documentation.
I am a newbie with firebase and trying to use this as the backend for an android app to store data. The format of the data is a key,value pair.
This is the code that I am using to store the data :
Map<Integer, PersonData> map = new HashMap<Integer, PersonData>();
map.put(PersonData.getID(), new PersonData("abcd", 12345));
Firebase ref = new Firebase(url).push();
ref.setValue(map);
Due to the push reference being used the data is getting stored like this :
-J5upSABqTLJ1Wfu-jFq
12345
id: 12345
name: abcd
Where-as I want the data to be store like this :
12345
id: 12345
name: abcd
I am not entirely sure if the code sample above is the right way to store data. Since I want to be able to update the existing data at a later point in time . Any suggestions ?
EDIT 1: I am thinking I need to use push so that I don't over-write the existing data in the firebase repo.
I have just tried to get the data back using the getValue() method and I can only fetch data which is in MAP
EDIT 2: without using a push() method with my reference I can see that the any previous data is getting overwritten and only the latest information is available. I am wondering if they is a better way to obtain the reference and still maintain the previous information
So it looks like you have your own system of unique ids, in which case you shouldn't need to use the .push method (that is just a helper to get a unique ref for new data). So instead of push you should be able to do:
Map<Integer, PersonData> map = new HashMap<Integer, PersonData>();
map.put(PersonData.getID(), new PersonData("abcd", 12345));
Firebase ref = new Firebase(url).child("12345");
ref.setValue(map);
Assuming your id is "12345" and url is pointing at the location where you want to store all of your persons.
To update the data without overwriting, your ref would be:
Firebase ref = new Firebase(url).child("12345");
And instead of using .setValue you would want to use ref.updateChildren(updates). You can see how to structure the updates from the example in the docs:
Map<String, Object> updates = new HashMap<String, Object>();
updates.put("first", "Fred");
updates.put("last", "Swanson");
nameRef.updateChildren(updates);