How to delete multiple nodes in one request in firebase? - android

I have two nodes from one root and I want to delete the data from both of them in one request. Both sub-nodes has the same key. I tried this:
Firebase firebaseRef = new Firebase(<root_path>);
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put(<path_to_first_node>, key);
childUpdates.put(<path_to_second_node>, key);
listToRemoveRef.updateChildren(childUpdates, null);
But it removed data from only the first node

It looks like you're using the updateChildren function wrong. What you want to do is this
Firebase firebaseRef = new Firebase(<root_path>);
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("<path_to_first_node>" + key, null);
childUpdates.put("<path_to_second_node>" + key, null);
listToRemoveRef.updateChildren(childUpdates);
The second parameter to updateChildren doesn't set the value to null it is an optional completion listener (see documentation). So instead of passing null to it on the last line, you can just omit it.

Related

firebase replaced my data when restarting my app

My app will generate a gameKey everytime user logged in and clicked "start game" button. Variable "gameKey" is generated by the following code, and then I will save data under the gameKey. The problem is, whenever I restart my app, the Firebase replaced the whole data tree with a new gameKey generated.
What I would like to do is to generate a new gameKey without overwriting the old data every time when my app runs. It would be so glad if anyone can point out my problem, thanks so much!
final FirebaseDatabase database = FirebaseDatabase.getInstance();
UserId = mAuth.getCurrentUser().getUid();
DatabaseReference currentUserId = database.getReference("user").child(UserId);
gameKey = currentUserId.child("gameinfo").push().getKey();
Map<String, Object> game = new HashMap<>();
game.put(gameKey, new Game(tv_player1name.getText().toString(), tv_player2name.getText().toString(), tv_player3name.getText().toString(), tv_playerMename.getText().toString(), gameMode, gameDate ));
currentUserId.child("gameInfo").updateChildren(game);
Firebase Data:
- user
- 5xGKRXeHgThQy70lduPEp3mosTj1 (UID)
- gameInfo
-LLV0H0ZJwYT5M42Obfb
gameDate: "20180903_232015"
gameType: "HKMJ"
player1name: "peter"
player2name: "jenny"
player3name: "john"
player4name: "wilson"
*This is the gameKey generated: "LLV0H0ZJwYT5M42Obfb"
This is the code after your suggestions:
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference currentUserId = database.getReference("user").child(UserId);
currentUserId.setValue(new User(mAuth.getCurrentUser().getEmail(), UserPic));
gameKey = currentUserId.child("gameinfo").push().getKey();
Map<String, Object> game = new HashMap<>();
game.put(gameKey, new Game(tv_player1name.getText().toString(), tv_player2name.getText().toString(), tv_player3name.getText().toString(), tv_playerMename.getText().toString(), gameMode, gameDate ));
currentUserId.child("gameInfo").child(gameKey).updateChildren(game);
In addition, I tried to replace this line
game.put(gameKey, new Game(tv_player1name.getText().toString(), tv_player2name.getText().toString(), tv_player3name.getText().toString(), tv_playerMename.getText().toString(), gameMode, gameDate ));
with this line, same result
Game game = new Game(tv_player1name.getText().toString(), tv_player2name.getText().toString(), tv_player3name.getText().toString(), tv_playerMename.getText().toString(), gameMode, gameDate );
Appreciate so much for the help!
Firebase ScreenShot
To solve this, please change the following line of code:
currentUserId.child("gameInfo").updateChildren(game);
to
currentUserId.child("gameInfo").child(gameKey).updateChildren(game);
You are basically generating a random key but you aren't using it at all. So you need to pass the gameKey to the child() method as seen in my above code.
Edit: So solve the entire update process, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference gameInfoRef = rootRef.child("user").child(uid).child("gameInfo");
String key = gameInfoRef.push().getKey();
Map<String, Object> game = new HashMap<>();
game.put("player1name", tv_player1name.getText().toString());
game.put("player2name", tv_player2name.getText().toString());
game.put("player3name", tv_player3name.getText().toString());
game.put("playerMename", tv_playerMename.getText().toString());
game.put("gameMode", gameMode);
game.put("gameDate", gameDate);
gameInfoRef.child(key).updateChildren(game);

Add element to end of a list - AWS DB from Android

I have a list item within AWS NoSQL DB.
I want to add a String value to the end of that list. My code is the following:
HashMap<String, AttributeValue> primaryKey = new HashMap<>();
AttributeValue key = new AttributeValue()
.withS(Array1[x]);
AttributeValue range = new AttributeValue()
.withS(Array2[x]);
primaryKey.put("XXXXX", key);
primaryKey.put("XXXXX", range);
try {
UpdateItemRequest request = new UpdateItemRequest()
.withTableName("XXXXXXXXXXXXXXXX")
.withKey(primaryKey)
.addAttributeUpdatesEntry(
"groups", new AttributeValueUpdate()
.withValue(new AttributeValue().withS(groupID))
.withAction(AttributeAction.ADD));
dynamoDBClient.updateItem(request);
Unsurprisingly this just overwrites the entire list in the AWS DB with the string rather than adding a new element to the list.
Is there anyway to do this without having to download the whole list, adding the string and then re-uploading? Would be allot cleaner to just ask that a new element is added to the end of the list.
Figured it out if anyone is having a similar issue.
Rather than trying to add an element to the "groups" field which is a list I changed the field in DynamoDB to a string set and adjusted the code as follows:
try {
UpdateItemRequest request = new UpdateItemRequest()
.withTableName("XXXXXXXXXXX")
.withKey(primaryKey)
.addAttributeUpdatesEntry(
"groups", new AttributeValueUpdate()
.withValue(new AttributeValue().withSS(groupID))
.withAction(AttributeAction.ADD));
dynamoDBClient.updateItem(request);
This now adds a new element to the end of the string set
I believe you're are actually looking for this:
UpdateItemRequest request = new UpdateItemRequest();
request.setTableName("myTableName");
request.setKey(Collections.singletonMap("hashkey",
new AttributeValue().withS("my_key")));
request.setUpdateExpression("list_append(:prepend_value, my_list)");
request.setExpressionAttributeValues(
Collections.singletonMap(":prepend_value",
new AttributeValue().withN("1"))
);
dynamodb.updateItem(request);
Example taken from: How to update a Map or a List on AWS DynamoDB document API?

Give unique child Key value for User using Firebase push() Method

How to give user defined key value in push(), instead of unique value created by push?
This is what am currently doing:
User user = new User(Editname.getText().toString(),
Editpid.getText().toString(),Editsem.getText().toString());
mRef.child("users").push().setValue(user);
.push() will create a new item with a unique reference.
You can use updateChildren() to update instead. For example,
User user=new User(Editname.getText().toString(),Editpid.getText().toString(),Editsem.getText().toString());
Map<String, Object> itemValues = user.toMap();
Map<String, Object> childUpdates = new HashMap<>();
// Define the key value here
String username = "yourKeyValueHere";
childUpdates.put("/users/" + username, itemValues);
mDatabase.updateChildren(childUpdates);
You might have to add something similar to the following to your User class.
#Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put("name", name);
result.put("pid", pid);
result.put("sem", sem);
return result;
}
Simplest way is to specify the child key with the child method:
User user = new User(Editname.getText().toString(),
Editpid.getText().toString(),Editsem.getText().toString());
mRef.child("users").child(user.pid).setValue(user);
Where I specify user.pid, you can use whatever unique key you use to identify the user (typically when using Firebase Authentication this would be user.getUid()).
This is one way to do it assuming we want to use the User's name as unique key:
User user = new User(Editname.getText().toString(),
Editpid.getText().toString(),Editsem.getText().toString());
String uniqueKey = user.getName();
//You could use something else for quick reference since two users can have the same name
mDatabaseReference.child("users").child(uniqueKey).push().setValue(user);

Firebase , second push() in same method does not work

In my app , there is an activity which upon clicking the save button, 2 sets of data in 2 different places should be made by push(), Since in both places an unique id is needed.
I have followed the sample code in the Firebase guide and added the second push
String userId = auth.getCurrentUser().getUid().toString();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
DatabaseReference firstDatabaseRef = reference.child("first");
DatabaseReference secondDatabaseRef = reference.child("second").child(userId);
String key = firstDatabaseRef.child(userId).push().getKey();
First first = new First(firstAmount,key,firstName);
Map<String, Object> firstValues = first.toMap();
String keySecond = secondDatabaseRef.child(key).push().getKey();
Second second = new Second(secondName,secondAmount,keySecond,key);
Map<String, Object> secondValue = second.toMap();
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/first/" + userId + "/" + key, firstValues);
childUpdates.put("/second/" + userId + "/" + key + "/" + keySecond, secondValue);
reference.updateChildren(childUpdates);
The result that i got for first was exactly as i expected but for second , instead of creating second/<userId>/<key>/<keySecond>/children, i get this :
"second" : {
//userId
"5TQLPlGf4mbcBRKesQwR30fH1L22" : {
//key
"-KL1030IywlNpkTGC7mU" : {
"secondAmount" : "147",
"Key" : "-KL1030IywlNpkTGC7mU",
"secondName" : "secondName",
"keySecond" : "-KL1030PZlHqD_asSR_8",
}
}
}
Instead of having the final children in another unique id, which by the way is recorded in the keySecond, they are all added directly to the key.
This cannot be accepted since every key must have many keySecond.
I hope that i explained my problem correctly.
Please tell me what am i doing wrong.
How should i modify my code or should i reconsider my data structure completely ?
This is a puzzle. I copy/pasted the code you posted and created stubs for First and Second. Running with Firebase 9.0.2 produced the result shown below, which I believe is what you are expecting. Are you running with a different Firebase version? Is it possible the JSON you posted was produced by a different version of the code you posted?
{
"first" : {
// userId
"ypx8RB3eglTBRPeUT7laQVQ1PZQ2" : {
// key
"-KL3rXeYrscFQNrVQnHb" : {
"firstAmount" : "FirstAmount",
"firstKey" : "-KL3rXeYrscFQNrVQnHb",
"firstName" : "FirstName"
}
}
},
"second" : {
// userId
"ypx8RB3eglTBRPeUT7laQVQ1PZQ2" : {
// key
"-KL3rXeYrscFQNrVQnHb" : {
// keySecond
"-KL3rXe_JyY9Vz2U-NES" : {
"Key" : "-KL3rXeYrscFQNrVQnHb",
"keySecond" : "-KL3rXe_JyY9Vz2U-NES",
"secondAmount" : "SecondAmount",
"secondName" : "SecondName"
}
}
}
}
}
When processing the updateChildren(), the Firebase Database loops over the children that you pass and for each key it essentially does a setValue() with the value you passed.
That means that if you have children with overlapping keys, the value of one of those keys will be written last. The order of these is undefined.
In your case it's fairly easy to merge the updates together:
String key = firstDatabaseRef.child(userId).push().getKey();
First first = new First(firstAmount,key,firstName);
Map<String, Object> firstValues = first.toMap();
String keySecond = secondDatabaseRef.child(key).push().getKey();
Second second = new Second(secondName,secondAmount,keySecond,key);
Map<String, Object> secondValue = trans.toMap();
firstValues.put(keySecond, secondValue); // This is the main change
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/first/" + userId + "/" + key, firstValues);
reference.updateChildren(childUpdates);

Setting Firebase server time in Android App

I have this code in my Android application, creating a new record in Firebase.
Firebase searchRef = myFirebaseRef.child("searches");
Firebase newPostRef = searchRef.push();
Map<String, String> search = new HashMap<String, String>();
search.put("start", start_address);
newPostRef.setValue(search);
String postId = newPostRef.getKey();
How would I go about inserting the ServerValue.TIMESTAMP into this record?
Use the below code to set the timestamp to a particular node
setValue(ServerValue.TIMESTAMP);

Categories

Resources