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);
Related
I am trying to push the form data to the firebase-firestore. And I also did it successfully. But, the problem is that whenever I am trying to submit the form data again and again it just updates the last data with the current data.
Actually, my requirement is that whenever the user hit the submit button. It creates a document with a random id and stores the all data into that specific id that is generated.
You are specifying the document ID in .document() so it'll overwrite the same document. If you want a document with a random ID on every click, try using add() instead as shown below:
val collectionRef = FirebaseFirestore.getInstance().collection("Maintainance")
collectionRef.add(user).addOnCompleteListener(...)
Alternatively, you can leave .document() empty to get a DocumentReference with a random ID:
val userDocument = FirebaseFirestore.getInstance().collection("Maintanance").document() // <-- don't pass an ID
In addition to #Dharmaraj answer:
CASE_1: In a case where you need to track each user's all submitted forms, probably from your explanation you may need to organize each user's form.
Therefore if you need to organize each user's form then create another sub-collection [example: document(userId).collection("USER_FORMS")] within userID document like this:
val documentRef = FirebaseFirestore.getInstance().collection("Maintainance").document(UserUtils.user?.id.toString()).collection("USER_FROMS").document();
CASE_2 : In a case where you need to make your own custom document ID:
1- make a random number or string or any other data type.
2- The random number/string variable must be local to the code block/method that will execute the form submision function.
3- use the number/string generated as the form document Id like this:
//This must be local so as user clicks submision button so as it generates new random number;
val randomFormId = "generateThenumberOrStringAndInitializeTheVariable";
Then use the random number as the form document Id like this:
val documentRef = FirebaseFirestore.getInstance().collection("Maintainance").document(UserUtils.user?.id.toString()).collection("USER_FROMS").document(randomFormId);
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(...).
I have already seen the code to store a single point in firebase. But what I want to know is how to store whole polylines in firebase database? A decoded polyline is basiclly List. I want to know how to store many such type of lists in firebase so that I can retrieve later and perform operations on whole polyline.
Firebase use JSON format Database
Pass types that correspond to the available JSON types as follows:
String
Long
Double
Boolean
Map
List
you can pass any of data type a value in setValue() method and Lists and Map ,too.
Example:
Firebase ref = new Firebase("<my-firebase-app>/names"):
String[] names = {"John","Tim","Sam","Ben"};
List nameList = new ArrayList<String>(Arrays.asList(names));
// Now set value with new nameList
ref.setValue(nameList);
you can pass your custome object list,too.
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.