I have the following Firebase database structure. uIds
is a type of List<String>
. I am trying to add another uId under uIds
with an incremented index. setValue()
and updateChildren()
would require me to retrieve existing data, and push()
will add an item with a randomly generated string as a key instead of an incremented index. Is there a simpler way that does not require to retrieve the existing data? Thanks!
"requests" : {
"request001" : {
"interests" : [ "x" ],
"live" : true,
"uIds" : [ "user1" ] // <---- from this
},
"request002" : {
"interests" : [ "y" ],
"live" : true,
"uIds" : [ "user2" ]
}
}
Edit:
Sorry for the unclarity. Let me elaborate to make it clear. Say I have the above database and want to update it to the following.
"requests" : {
"-KSVYZwUQPfyosiyRVdr" : {
"interests" : [ "x" ],
"live" : true,
"uIds" : [ "user1", "user2" ] // <--- to this
},
"-KSl1L60g0tW5voyv0VU" : {
"interests" : [ "y" ],
"live" : true,
"uIds" : [ "user2" ]
}
}
ishmaelMakitla's suggestion, mDatabase.child("requests").child("request001").setValue(newRequest)
, will overwrite the "request001" with "newRequest". So I should retrieve the existing data of "request001" and add "user2" to the list uIds
. It will be something like this:
mDatabase.child("requests").child("request001").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Request newRequest = dataSnapshot.getValue(Request.class);
newRequest.uIds.add("user2");
mDatabase.child("requests").child("request001").setValue(newRequest);
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
But I am wondering if this process is necessary since what I am trying to do is simply to add one item to the list uIds
.
Cloud Storage for Firebase allows you to list the contents of your Cloud Storage bucket. The SDKs return both the items and the prefixes of objects under the current Cloud Storage reference. Projects that use the List API require Cloud Storage for Firebase Rules Version 2.
Inherited from Query.orderByChild. Generates a new Query object ordered by the specified child key. Queries can only order by one key at a time. Calling orderByChild() multiple times on the same query is an error. Firebase queries allow you to order your data by any child key on the fly.
The Firebase documentation on creating data that scales proposes that you use a different data structure:
"requests" : {
"-KSVYZwUQPfyosiyRVdr" : {
"interests" : { "x": true },
"live" : true,
"uIds" : {
"user1": true,
"user2": true
}
},
"-KSl1L60g0tW5voyv0VU" : {
"interests" : { "y": true },
"live" : true,
"uIds" : {
"user2": true
}
}
}
Here are a few of the reasons why this data structure works better:
ref.child("uUids").child("user3").setValue(true)
I have started re-iterating to myself: whenever you find yourself doing array.contains("xyz")
, you should probably be using a set instead of an array. The above mapping with "key": true
is an implementation of a set on Firebase.
Some people may think arrays are a more efficient way of storing the data, but in the case of Firebase that is not true:
What you see:
"uIds" : [ "user1", "user2" ]
What Firebase stores:
"uIds" : {
"0": "user1",
"1": "user2"
}
So storing a set is pretty much the same:
"uIds" : {
"user1": true,
"user2": true
}
Not sure what you mean when you say setValue, etc require you to retrieve existing data. The basic flow for inserting new record is as follows:
private DatabaseReference mDatabase;
// get reference to your Firebase Database.
mDatabase = FirebaseDatabase.getInstance().getReference();
//and here you add a new child to your 'requests' collection
//I am assuming you have a Request model like this..
Request newRequest = new Request(some-params);
mDatabase.child("requests").child(someRequestId).setValue(newRequest);
You can take a look at basic usage guide for Saving Data on Android Firebase.
Update:
Following your comment - I think what you are looking to do can be achieved like this:
You use the push()
method which generates a unique ID every time a new child is added to the specified Firebase reference:
Firebase newRequestRef = mDatabase.child("request").push();
newRequestRef.setValue(newRequest);
This should do it.
I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With