Adding same key name values - android

If I want to add data with same key name but different values, how can I do it without replacing the existing ones? For example the database looks like this:
database
|______user1
|______sameKey: data1
|______sameKey: data2
if I use: DatabaseRef.child(user1).child("sameKey").setValue(data);, it will overwrite the sameKey with the new data, but I want it to simply be a different record of data. How to achieve that?

if you want to display a different record with the same key, just wrap it up under a push key, which is an alafanumeric random value
mDatabaseRef.child(user1).push().child("sameKey").setValue(data);
Now , if you just want to update the current data and not replace it
you will need to use a map and use updateChildren take a look at this example
Map<String,Object> mapData = new HashMap<>();
mapData.put("sameKey",data);
mDatabaseRef.child(user1).child(sameKey).updateChildren(mapData).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// Write was successful!
// ...
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Write failed
// ...
}
});
with this you will only replace data that is updated and not the entire node
take a look at Updating or deleting data here
https://firebase.google.com/docs/database/android/read-and-write?hl=en

Related

How do I use document reference to add field (prevent overwriting) in my document in Firestore?

First of all, I hope anyone could help adjust my code line using document reference as below.
As you can see from my firebase console below, my FaceEmotion-id document has Faceemotion and Timestamp field.
Using my codes below, everytime user gets different emotion, the firestore will overwrite the emotions. Hence I couldnt see what are the different emotions user get when using my app and the different time he/she has used my app.
I need to prevent overwriting for the two fields mentioned above. Please help me. What I want is to add fields in the document not overwriting it.
One more, I have no idea how to generate different id for the document named FaceEmotion-id. I actually had referenced the document beforehand using Uid as you can see from my code below. But for the subdocument in the "Result" collection. I cant seem to find a way to make it unique.
This is my codes:
public static final String TAG = "TAG";
FirebaseAuth fAuth;
FirebaseFirestore fStore;
String userID;
String FaceEmotion;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detection);
fAuth = FirebaseAuth.getInstance();
fStore = FirebaseFirestore.getInstance();
StartQues = (Button) findViewById(R.id.view_question);
StartQues.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String Emotion = EmotionType.toString();
userID = fAuth.getCurrentUser().getUid();
FaceEmotion = "FaceEmotion";
DocumentReference documentReference = fStore.collection("users").document(userID).collection("Result").document("FaceEmotion-id");
//DocumentReference documentReference = fStore.collection("users").document(userID).collection("FaceEmotion").document(Emotion);
Map<String,Object> user = new HashMap<>();
user.put("FaceEmotion",Emotion);
user.put("timestamp", FieldValue.serverTimestamp());
documentReference.set(user).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "onSuccess: Data has been saved "+ userID);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "onFailure: " + e.toString());
}
});
It sounds like you want to store a list of timestamps and emojis. If you want to store those in a single document, the logical data structure would be to store them in an array/set with something like this:
user.put("FaceEmotion",Emotion);
user.put("timestamp", FieldValue.serverTimestamp());
documentReference.update("emotions", FieldValue.arrayUnion(user))
Every time this code runs, it will add a new item to the emotions array in the document.
Also see the Firebase documentation on updating elements in an array.

Firestore SetOptions.mergeFields() not working as expected using POJO

I'm trying to update a specific field in a document using POJO, as written in the doc. I could use SetOptions.mergeFields(). But it's updating other fields with null instead of keeping the other fields (which excluded from mergeFields) untouched. Is it intended?
Here is my code :
UserModel userModel = new UserModel();
userModel.setStatus(0);
setTask = documentReferenceToUse.set(userModel, SetOptions.mergeFields("status"));
setTask.addOnSuccessListener(new OnSuccessListener<Void>()
{
#Override
public void onSuccess(Void aVoid)
{
if (!emitter.isDisposed())
{
emitter.onComplete();
}
}
}).addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
if (!emitter.isDisposed())
{
emitter.onError(e);
}
}
});
And here is my document structure :
[Solved]
Turned out the issue came from my Firebase wrapper code. So there is no actual problem on the Firebase SDL side.
Edit: After taking another closer look at your code, I found that you need to change this line of code:
setTask = documentReferenceToUse.set(model, SetOptions.mergeFields("status"));
with:
setTask = documentReferenceToUse.set(userModel, SetOptions.mergeFields("status"));
You are passing as the first argument, not the object that you have just created but another one. So, the correct object that must be used is: userModel.
You can also use another approach, by getting that entire object from the database. Having the object, you can use setters to change the value of the fileds beneath it. After you have used the setters, you can use set() method directly on the reference to add the object the database.
documentReferenceToUse.set(userModelFromDatabase);
You can also use a Map in order to make an update:
Map<String, Object> map = new HashMap<>();
map.put("status", 0);
documentReferenceToUse.update(map);

how to check if a collection contains certain sub collection or not in firestore

i want to make this type of collection in my firestore
where chatRooms will be my collection name, combination of myUid and opponentsUid will be my sub-collection in which different documents will be placed. My problem is i want to check if my collection contains sub-collection named myUid_opponentsUid or opponentsUid_myUid and i am not able to search a best query for doing this.
All i know is that we can fetch the whole list and then check if it contains the specific room or not, but its a lengthy process, so i want to better method for it.
Thanks in advance.
There are a few misconceptions in your question to clear up first:
In Firestore collections don't really exist as distinct entities. It's the documents inside a collection that cause it to become visible.
Also, collections can only contain documents, which in turn can contain collections, but the structure must alternate, so you can't have a collection called chatRooms that contains a collection myUid_opponentUid. Inside chatRooms there must be a document.
So if chat rooms contain messages, a straightforward way to do what you want is to create a document that represents that chatRoom. Then within that create a subcollection for the messages.
If you sort the UIDs before creating the composite chatRoom key you can then test whether or not the chat room exists by using a single get(). The structure would look like this:
chatRooms/(uid-pair)/messages/(message-id)
Note that you don't actually need to store anything at the chatRoom/(uid-pair) level to create children at the messages level: you can just create new messages and listen directly.
Try to Read Total Number of child .! Hope this thing may helps you.and if you want to implement your own api then try using Firebase Functions..and last thing I want to add is that if You want to add get Count without reading number of child you have to implement one method that getChildCount before storing data and then append them with key like JiGh_31GA20JabpZBfa,1` and only read keys and then use comma separator and you will get your result that this parent contains child or not.?
DatabaseReference myRef = database.getReference();
//You can use the single or the value.. depending if you want to keep track
String id= UUID.randomUUID().toString();//randomID for task
Object object=new Object ();
public int chidcount(String child){
string childcount="0";
//You can use the single or the value.. depending if you want to keep track
myRef.child(child).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snap: dataSnapshot.getChildren()) {
childcount=snap.getChildrenCount();
Log.e(snap.getKey(),snap.getChildrenCount() + "");
}
addvalue(childcount);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private addvalue(String childcount){
object=setid(id);
object=setname("name");
getchildCount("object");
mdatabaseRef.child("rating").child(manager.getId()+childcount).child(currentEmployee.getId()).child(id).setValue(rating);}
I know I am late.
Posting for future users.
Try this:
DocumentReference datab = db.collection("collection_name").document("Doc_name");
datab.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if(documentSnapshot.contains("field_name"))
{
Toast.makeText(YourActivity.this, "Child exixts.", Toast.LENGTH_SHORT).show();
}
else
Toast.makeText(YourActivity.this, "Doesnt exits.", Toast.LENGTH_SHORT).show();
}
});
For Firebase Firestore to check whether the document has entries (fields), Use this command
firebaseFirestore.collection("Users").document(userId)
.addSnapshotListener {
documentSnapshot, _ ->
if (documentSnapshot!!.contains("name")) {
Log.i("Name", "Name exists")
} else {
Log.i("Name", "Name doesn't exists")
}
}

New Child is not created in firebase

i am trying to save new files in numbered order. so there is a count child it get updated but no new child is created
this is the code
databaseReference.child("AdminList").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long key= (long) dataSnapshot.child("count").getValue();
databaseReference.child("AdminList").child("count").setValue(key+1);
databaseReference.child("AdminList").child(String.valueOf(key+1)).child("uid").setValue(uid);
databaseReference.child("AdminList").child(String.valueOf(key+1)).child("Aname").setValue(fname);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});``
You are trying to store your data in a "continuous" manner, which is something that JSON objects just aren't designed do. If you are looking for an ordered list, use the priorities property, or you can order the data on the client side. This means that you can just store the data, and then either order client-side, or prioritize the children. I would look to do something like:
databaseReference.child("AdminList").child("uid").setValue(uid);
Use push() to create new child nodes:
databaseReference.child("childName").push();

FireBase Android Need 1 value saved under a single user

I have the following data structure on firebase for the user MF0qeRA4p7djfjgXxqwFOck3m6p02. I want to get the value of item3 to populate a single field into the User interface on an Android App. I have been looking through samples on Stackoverflow, but all I have found are outdated and do not work with the current version of firebase. I'm new to firebase completely and this is my first app on android. I've got the oncreate user method to populate the users email address and add the 4 item fields, but retrieving the data I'm completely lost and I am not sure where to even begin.
-Users
---MF0qeRA4p7djfjgXxqwFOck3m6p02
------item1:"1"
------item2:"2"
------item3:"3"
------item4:"4"
According to what I can identify is, you are facing problem retrieving data from this reference. Here is the code:
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Users");
databaseReference.child("MF0qeRA4p7djfjgXxqwFOck3m6p02").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> map=(Map<String, Object>)dataSnapshot.getValue();
String item3=(String)map.get("item3");
display(item3);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Hope this helps.
You can create a custom model and inside you can insert elements. Something like this:
public class Item {
private List<Object> ojects;
}
There you can save instance of Item on database. In this case you have more controll. Other case is to use push() method, that will generate a new encoded key, something like this:
mDatabase.child("items").push().put(new Object());

Categories

Resources