I am developing chat app and need help regarding its group structure.
I already manage structure till groupIcon but now how to create members structure with 0 ... 1... 2... etc...?
Here is my code :
private void createGroup(String strGroupName) {
RootRef = FirebaseDatabase.getInstance().getReference("GroupDetail");
String strGroupID = RootRef.push().getKey();
HashMap<String, String> groupMap = new HashMap<>();
groupMap.put("_id", group_id);
groupMap.put("adminId", admin_id);
groupMap.put("adminName", admin_name);
groupMap.put("createdAt", created_at);
groupMap.put("groupIcon", group_icon);
RootRef.child(strGroupID).setValue(groupMap)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast.makeText(activity, "Group created
successfully",Toast.LENGTH_SHORT).show();
}
});
}
In the members property you have an array. I'd actually suggest first changing that model to a map like this:
members: {
"5c6260...63d00": true,
"5c6262...63d02": true
}
Reason for that are that you'll typically want each user to be a member of the chat room at most once, while an array can have the same value multiple times. Using a map automatically prevents this problem, since keys are guaranteed to be unique in a map (and in Firebase's JSON). For more on this, also see my answer here: Firebase query if child of child contains a value
The above structure you can write with a Map<String, boolean> in Java:
Map<String, boolean> members = new Map<>();
members.put("5c6260...63d00", true);
members.put("5c6262...63d02", true);
groupMap.put("members", members);
Related
I am using addOnCompleteListener, but I need to setValue to more than one child at time, it will not be good if I check if 1st child updated then update the 2nd then the 3rd ... etc, it will be very complicated
Also I need to test addOnFailureListener, addOnCanceledListener ,and when they will be triggered and what the best action should be taken in these case
From the docs:
public Task<Void> setValue (Object value)
Set the data at this location to the given value. Passing null to setValue() will delete the data at the specified location. The native types accepted by this method for the value correspond to the JSON types:
Boolean
Long
Double
String
Map
List
Therefore if you have multiple setValue(), you can do the following:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");
Map<String, Object> values = new HashMap<>();
values.put("name","peter");
values.put("age","100");
ref.setValue(values).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
System.out.println("completed");
}
});
Of you can use a pojo class instead of map.
https://firebase.google.com/docs/reference/android/com/google/firebase/database/DatabaseReference#setValue(java.lang.Object)
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
I'm trying since a while to add timestamp on my posts in Firebase, but I'm sadly unsuccessful. I have already tried many advises from stackoverflow, but none worked. Please help me on how to add a timestamp field under each post.
I would to know what's wrong with my code.
final DatabaseReference newPost = mDatabase.push();
mDatabaseUser.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Long timestamp = (Long) dataSnapshot.getValue();
System.out.println(timestamp);
newPost.child("title").setValue(title_val);
newPost.child("desc").setValue(desc_val);
newPost.child("image").setValue(downloadUrl.toString());
newPost.child("uid").setValue(mCurrentUser.getUid());
newPost.child("username").setValue(dataSnapshot.child("name").getValue()).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
startActivity(new Intent(PostActivity.this, MainActivity.class));
}
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mDatabaseUser.setValue(ServerValue.TIMESTAMP);
mProgress.dismiss();
Firebase Database structure:
{
"Blog":{
"-Ke1osQRFVs0fuqx9n18":{
"desc":"again again",
"uid":"FBwMzHJGP4U10LnLOwluy4BVyJ52",
"username":"OziBoo"
}
},
"Users":{
"vi6Qd1AafidNGGV4roBhdLPZYGN2":{
"image":"firebasestorage.googleapis.com/v0/b/agrodesk-b30ff.appspot.com/...",
"name":"Ozi"
}
}
}
There are a lot of error and misuse in your code. Please understand this first:
ref.addValueEventListener(...) is used for listening to every changes made in data referenced by ref
ref.setValue(yourValue) is used to set the value of data referenced by ref object
setValue(...).addOnCompleteListener(...) is used if you want to execute something after value has been updated
If I understand it correctly, all of your sample code you write for writing value into database, right? But you, not knowingly, used addValueEventListener() instead.
So your code to write the value into new child inside "Blog" should be like this:
// Here I use HashMap to make it more simple
// You can (and better to) use your custom object as value container
HashMap<String, Object> value = new HashMap<>();
value.put("title", "your-title");
value.put("desc", "your-desc");
value.put("timestamp", ServerValue.TIMESTAMP);
// ... etc
// the following code will create a reference object pointing at "Blog"
DatabaseReference ref = FirebaseDatabase.getInstance().getRreference("Blog");
// the following code will make a new child inside data referenced by ref (in this case, "Blog")
DatabaseReference newBlog = ref.push();
// the following code is the code that actually update the data of referenced point
newBlog.setValue(value)
// addOnCompleteListener is optional
.addOnCompleteListener(new ... {
// code placed here will be executed when your data is updated
...
});
Hope this helps.
Note:
There I just show you what you want to achieve for this case and this case only. Please read more documentation, guide, and tutorial about Firebase Database. It might take long, but once you understand it, it's actually quite simple.
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());
I'm trying to add a new child using the DatabaseReference in my Firebase Android app. I'm doing:
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference()
mDatabase.child("childToAdd").setValue(1);
I can do this with a regular Firebase Reference as it would add the child to the database if it isn't there.
How could I go about doing this with DatabaseReference?
Edit: Thanks for all the suggestions but I'm having issues with the following code. When it enters the if block it does not push the data onto the database.
https://gist.github.com/rounaksalim95/a5cba332400c6caf8320f15b0cbf06e8
When I try this with the old Firebase reference I get error code 11 (User code called from firebase runloop) and with the new database reference I get error code -3 (PermissionDenied even though I have no security rules).
Update:
I got it to do what I wanted to using a single value event listener:
Firebase userRef = new Firebase(BASEURL + "userData");
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child(user.getUid()).getValue() == null) {
userRef.child(user.getUid()).setValue(1);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
However database reference doesn't let me add values like this.
You'll need to call push() to generate a unique key for the new data:
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference()
mDatabase.push().setValue(1);
This will append the new value at the end of the list.
By combining the push() and child() methods, you can create multiple lists of children in the database:
mDatabase.child("numbers").push().setValue(1);
mDatabase.child("numbers").push().setValue(53);
mDatabase.child("numbers").push().setValue(42);
mDatabase.child("letters").push().setValue("a");
mDatabase.child("letters").push().setValue("z");
mDatabase.child("letters").push().setValue("c");
See the section append to a list of data in the Firebase documentation.
Another post mentioned to check your gradle app file to ensure you have the latest version of the Firebase as follows:
compile 'com.google.firebase:firebase-core:10.0.1'
compile 'com.google.firebase:firebase-database:10.0.1'
I think this should fix many issues that could arise from using older versions.
I hope this helps.
You cannot add anything to the database if you're not authorized. You can do one of the following:
Either set this to your rules tab in firebase console:
{
"rules": {
".read": true,
".write": true
}
}
Or you must create an authentication first (try with email/pass) and create user with
createUserWithEmailAndPassword(email, password)
and then sign in with:
signInWithEmailAndPassword(email, password)
and you need to enable sign-in with email/pass in your console as well.
And then you can write data to your database.
Use push() before set value in the firebase. It will create new user every time when you send value in the database.
Check this sample, it may help you out.
public class FirebaseUserDetails
{
private String mDisplayName;
public String getmDisplayName() {
return mDisplayName;
}
public void setmDisplayName(String mDisplayName) {
this.mDisplayName = mDisplayName;
}
}
Add your value to firebase database,
FirebaseUserDetails firebaseUserDetails = new FirebaseUserDetails();
firebaseUserDetails.setmDisplayName("arunwin");
DatabaseReference pathReference = FirebaseDatabase.getInstance().getReference().child("contacts");
pathReference.child("arun").setValue(firebaseUserDetails).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
}
});
And your result value will be added in your database like the below,
contacts:
arun:
mDisplayName:"arunwin"
In my case i am adding new child like this!
NOTE : Here i am adding new child refresh_token to my firebase database
FirebaseDatabase.getInstance().getReference().child("RegistrationModel").child(userId)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, String> stringStringHashMap =(Map<String, String>) dataSnapshot.getValue();
stringStringHashMap.put("refresh_token",refreshedToken);
FirebaseDatabase.getInstance().getReference().child("RegistrationModel").child(userId)
.setValue(stringStringHashMap);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});