Update object's field in Firebase - android

My project has 2 Apps: Admin-app and Client-app. First, I need to use the Admin-app in order to put data into Firebase and here is my data class
public class AllData {
private String placeName;
private ArrayList<String> category;
private String address;
private String openingHour;
private String website;
private HashMap<String, String> review; }
and I use following code to set data into Firebase
AllData alldata = new AllData(placeName, category, address,
, openingHour, website, null);
mDatabaseReference = mFirebaseDatabase.getReference().child("Store Data");
DatabaseReference storeData = mDatabaseReference.child(placeName);
storeData.setValue(alldata);
I have set the review field as null because I want to let my users review each place on Client-app and sync it into Firebase to the review field as HashMap<UserName, Review>
I use these codes in client-app to push review to Firebase
HashMap<String, String> reviewMap = new HashMap<>();
reviewMap.put(UserName, review);
mDatabase = FirebaseDatabase.getInstance();
mReference = mDatabase.getReference().child("Store Data").child(selectedPlace.placeName).child("review");
mReference.push().setValue(reviewMap);
This is not a right approach but that's all I could. What I want is to update the user's review to the AllData's review field in the Firebase asynchronously. How can I make this happen? Every answer is appreciated!

You can simply use setValue() method directly on the reference without using a HashMap like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("Store Data").child(selectedPlace.placeName).child("review").setValue(yourValue);
In which yourValue is the value which you want to set to the review key.
Hope it helps.

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);

Firebase databaste structure advice

I need some advice on how to structure my database in order to query it correctly. From what I've understood the structure of the database is everything, but I am not sure I am using it correctly.
Basically my app is supposed to retrive data from an api and display that in a listview. Every item (newspost) in the listview can have comments from firebase users.
So I have "NewsPost" , "User" and "Comment" models that looks like this.'
NewsPost.class
private String id;
private String date;
private String title;
private String commentsNumber;
private List<Comment> comments;
private String imageUrl;
User.class
private String userName;
private String userAvatar;
private String firstName;
private String lastName;
private String eMail;
Comment.class
private UUID uuid;
private String postId;
private String message;
private String postDate;
private String userAvatar;
private String userName;
So this is how I tried to store it:
AND this is how I try to get the comments when a user clicks to read the comments for the specific newsPostItem in the listView with the newsPostId as a query param.
public void getComments(String postId) {
comments = new ArrayList<>();
Query query = databaseReference.child("comments").orderByChild(postId).equalTo(postId);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot issue : dataSnapshot.getChildren()) {
Comment comment = issue.getValue(Comment.class);
comments.add(comment);
}
Log.d("GETCOMMENTS", "SNAPSHOT EXISTS");
view.onCommentsLoaded(comments);
}
else{
view.onCommentsLoaded(comments);
Log.d("GETCOMMENTS", "SNAPSHOT NOT EXISTS");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
view.onCommentsLoaded(comments);
Log.d("GETCOMMENTS", databaseError.getMessage());
}
});
}
My Question is, amidoinitrite?
I got a firebase downloaded limit for this month warning (10 GB) which shouldn't happen because I am the only user right now.
Any help is appreciated!
Sidenote: The userAvatar is stored in a byte[] in the database, no good?
When using Firebase, there are a few rules that we need to keep in mind. In your particular case, i recomand you using denormalization and to change the database to be as flatten as possible. For a better understanding, i recomand you see this video, Denormalization is normal with the Firebase Database. Because Firebase Realtime Database cannot query over multiple properties, it ussaly involves duplication data. So this things are normal when it comes to Firebase. In your particular case, i recomand you doing both things.
I also recomand you read this post, Structuring your Firebase Data correctly for a Complex App. It's very well explained and will help you take the best decision.
You need to know that there is no perfect sturcture for a database. You need to structure your database in a way that allows you to read/write data very easily and in a very efficient way. If you don't know yet, Firebase has launched a new product named Cloud Firestore. Realtime Database does not scale automatically while the new Firestore does.
Currently you are adding "NewsPostID" as root node inside "comments".
This structure will consume more storage size because every new comments is added as new root inside "comments" node.
Suppose we wants to query that : Specific user's all comments for any single date. so, in this case current structure is complex to apply query.
You can change structure like :
"comments"
-"userEmail"
- "NewPostDate"
- "NewpostID:15478"
-KHZzTwazaSd (this is random id)
-"message: hey.."
-"postDate: Date + 12:10PM"
-KHZzTwazaSd (this is random id)
-"message: Nice post.."
-"postDate: Date + 12:22PM"
- "NewpostID:54478"
-KHZzTwazaSd (this is random id)
-"message: Nice day"
-"postDate: Date + 10:45PM"
You can get all user related details from user table using "userEmail" from "comments". this will decrease node size and also will be helpful to query.

Firebase adding Child with specific Name / chrash when Name is referennce (to Firebase User) (Android)

So I try to make a Registration that automatically creates a child with the Name of the email, but the Program crashed.
DatabaseReference mDatabase;
private Firebase firebase;
private FirebaseAuth mAuth;
firebase.child("new5").setValue(arrayList);
mDatabase.child("new5").setValue(arrayList);
This two Options works perfectly but when i try to make it with the User:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String userEmail = user.getEmail().toString();
Toast.makeText(MainActivity.this,userEmail,Toast.LENGTH_SHORT).show();
mDatabase.child(userEmail).setValue(arrayList);
The Toast work, but when I add the last line it crash
Is there any way to solve this Situation or is there a simple way to connect a child created with "push()" with a User ?
The problem is that you are trying to use userEmail in the DatabaseReference which is not encoded. Firebase does not allow in it's key symbols like . (dot). So in order to solve this, you need to encode the email address like this:
name#email.com -> name#email,com
To achieve this, i recomand you to use the following methid:
static String encodeUserEmail(String userEmail) {
return userEmail.replace(".", ",");
}
And to decode the email, you can use the following method:
static String decodeUserEmail(String userEmail) {
return userEmail.replace(",", ".");
}

How to get a key of an object that was pushed just now in Firebase?

I want to create kind of registration without password and email. I use only nickname. So,I have a User class that has nickname field and other fields. So, I want to push new user and the thing that I want is to save its key because I will need it in the future when I have to get some user's data. So how can I get a key of an object that was already pushed?
Here is my code how I push:
User user = new User() ;
user.setNick(nick.getText().toString());
user.setScore(0);
Firebase fire = new Firebase(FirebaseConfig.URL) ;
//how to get key of this object? Is it possible before pushing?
fire.push().setValue(user);
To get the key, please use the code below:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference keyRef = rootRef.push();
String key = keyRef.getKey();
keyRef.setValue(user);
or
Firebase fire = new Firebase(FirebaseConfig.URL) ;
String pushKey = fire.push().getKey();
fire.child(pushKey).setValue(user);
Hope it helps.
It is not possible to get pushKey before you do push().
You can try this one instead.
Firebase fire = new Firebase(FirebaseConfig.URL) ;
String pushKey = fire.push().getKey();
fire.child(pushKey).setValue(user);

Getting Value from specified Key - Firebase/Android

I have run into an issue where I have each child off the root be a separate user account with a object (converted to string through gson). I create each user in the database during user registration.
DatabaseReference root = FirebaseDatabase.getInstance().getReference().getRoot();
Map<String,Object> map = new HashMap<String, Object>();
map.put(firebaseAuth.getCurrentUser().getUid(), "");
root.updateChildren(map);
Then save the user object in it using this method
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child(firebaseAuth.getCurrentUser().getUid());
Gson gson = new Gson();
String json = gson.toJson(this);
databaseReference.setValue(json);
Now I want to be able to pull the json from the firebase database but I can only get the userID key not the value. I am trying to avoid using a listener also.
This is how my database looks now:
-myapp-aaf46
-(userID): {json string}
I need to be able to get json string but I can only get it to return userId

Categories

Resources