Creating Specific Child While Messages Are Retrieving Android Studio - java

I am trying to make a message section in my app.
Model Description:
You can ignore DUYURU, it isn't related with topic.
child of DUYURU means author's uid.
Number represents messages unique index.
Model
My java-android code:
mRef = FirebaseDatabase.getInstance().getReference("Tests").child("DUYURU");
mRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
posts.clear();
for (DataSnapshot userMessages:snapshot.getChildren()) {
//These 2 values become null since childs are not exist
String sender = userMessages.child("sender").getValue(String.class);
String photoUri = userMessages.child("photoUri").getValue(String.class);
String uid = userMessages.getKey();
for (DataSnapshot dataSnapshot: userMessages.getChildren()) {
Post post = dataSnapshot.getValue(Post.class);
post.setPostInfo(sender,photoUri,uid);
post.setIndex(Integer.parseInt(dataSnapshot.getKey()));
posts.add(post);
}
}
Collections.sort(posts,Collections.<Post>reverseOrder());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.e(TAG, "onCancelled: ",error.toException() );
}
});
Then sender's value becomes null since there is no child called sender.
So how can i create a child if not exists while messages are retrieving.

//checking if object is not exist in for loop
if (!userMessages.hasChild("sender")) {
mRef.child(userMessages.getKey()).child("sender").setValue("sendername");
}

Related

onDataChange() method is never reached

I am trying to retrieve data from Firebase, but I don't know how. I have the following data structure in Firebase [1]: https://i.stack.imgur.com/vN7Ge.png:
![enter image description here][1]
I can retrieve the category title(sleep, Stress Relief, and Relax), but don't know how to retrieve the author.
dataSnapshot.child("author").getValue(String.class)) ; doesn't work.
.
databaseReference = FirebaseDatabase.getInstance().getReference().child("Category");
}
public void getDataFromFirebase() {
List<ParentItem> parentItemsList = new ArrayList<>();
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
String category = dataSnapshot.child("Category").getValue(String.class));
String author = dataSnapshot.child("author").getValue(String.class));
}
Log.d("TAG", "onDataChange: "+ parentItemsList);
}
UPDATE
now I have the following code to retrieve data, but onDataChange () is never reached.
list.add("Milena"); // this word shows in recyclerview
databaseReference = FirebaseDatabase.getInstance().getReference().child("Category");
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
list.add("M");
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String category = ds.child("Category").getValue(String.class);
list.add(category);
for (DataSnapshot data : dataSnapshot.getChildren()) {
author = data.child("author").getValue(String.class);
list.add(author);
}
}
}
firebase rules:
{
"rules": {
".read": "auth==true",
".write": "auth==true"
}
}
I have line list.add("Milena") to make sure the problem is with firebase, not the recycler view itself. Recycler view shows only the word "Milena". And I have line as the first line of OnDataChange method list.add("M"). The recycler view doesn't shows the letter.
I already added google-services.json file to my app and added this line to manifest <uses-permission android:name="android.permission.INTERNET"/>
Why I can't still retrieve data?
If you want get field author, you can more loop for dataSnapshot like this
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
String category = dataSnapshot.child("Category").getValue(String.class));
for(DataSnapshot data : dataSnapshot.getChildren()) {
String author = data.child("author").getValue(String.class));
}
}
hope this can solve your problem :)
I think that the problem is your reference points to Category and you want the author. Between category and authors there are 2 children ("Sleep" and "1").
So, I think the best to do is change this line:
databaseReference = FirebaseDatabase.getInstance().getReference().child("Category");
in this:
databaseReference = FirebaseDatabase.getInstance().getReference().child("Category").child("Sleep").child("1");
To solve this issue you have to iterate through the children twice, as seen in the following lines of code:
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference categoryRef = db.child("Category");
categoryRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
DataSnapshot snapshot = task.getResult();
for (DataSnapshot categorySnapshot : snapshot.getChildren()) {
String categoryName = categorySnapshot.getKey();
Log.d("TAG", categoryName);
for (DataSnapshot ds : categorySnapshot.getChildren()) {
String author = ds.child("author").getValue(String.class);
Log.d("TAG", author);
}
}
} else {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
}
});
But be aware that a child as Category: "Sleep" should not exist on the same level as 1, 2, and so on. Since the name of the category already exists as the key of a node, please remove those records:
In this way, you'll avoid a ClassCastException, as at the same level you have an object with two properties and a String one. So once you remove those children, the above code will work perfectly fine. If you however need a node to contain that information, I recommend you create a top-level node that will contain only the name of the categories.

Firebase Deleting A Value

I'm developing an app with Android Studio using Firebase. I want to delete a certain date but when I click on the delete button it does nothing. I can't reach to parent because it's a generated key. Any help would be appreciated.
private void deleteDate(){
String dateValue = showDate.getText().toString();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String userid = user.getUid();
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference().child("Users").child(userid).child("smokeFreeDays");
usersRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull #NotNull DataSnapshot snapshot) {
for (DataSnapshot userDataSnapshot : snapshot.getChildren()) {
String date = userDataSnapshot.getValue(String.class);
if (date.equals(dateValue)) {
snapshot.getRef().child(dateValue).removeValue();
} else if (!date.equals(dateValue)) {
snapshot.getRef().child(dateValue).removeValue();
}
}
}
#Override
public void onCancelled(#NonNull #NotNull DatabaseError error) {
Log.w("tag", "loadPost:onCancelled", error.toException());
}
});
}
My Database:
See my comment above for debugging the issue.
But as an overall hint, I'd recommend reconsidering the data structure under smokeFreeDays to look like this:
"smokeFreeDays": {
"2021-05-09": true,
"2021-05-10": true
}
The two changes in this structure:
The date format is now ordered year-month-day, which is better suited for querying. For example, you can get all smoke free days in 2021 with: usersRef.orderByKey().startAt("2021-").endAt("2021~").
We now use the date as the key, which means we no longer have to load all smokeFreeDays to find the value to delete. You can now delete the node once you know the date with: usersRef.child("2021-05-09").removeValue().

Cannot get reference to my auto generated push IDs in android

I am making an android app through android studio in java language. I have linked it to firebase Realtime database. There are auto generated push IDs as the last child. I want to retrieve my database values back in an activity. I am facing problem in giving reference to the push IDs.
This is what I have tried.
myRef = myfire.getReference().child("Data").child(strUID).child("Traffic").child("Wedding");
final String uid =myRef.getKey();
myRef.child(uid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() == null) {
Toast.makeText(getApplicationContext(),"Data Not Available",Toast.LENGTH_LONG).show();
} else {
String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();
category basic = new category(stData1,stData2,stData3,stData4);
tvBalance.setText(stData4);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Please provide a practical example.
Edit
This is my database structure:------------
Data>>
user id>>>>
Traffic>>>>
Wedding>>>>
Auto ID>>>
>stData1
>stData2
>stData3
>stData4 //I want to get this last value//
my json file
{
"Data" : {
"UyhzVqsz1BVFKoePa2NEmlPFu382" : {
"Traffic" : {
"Wedding" : {
"-MYKeSN8GZ8WbI-8TfVB" : {
"stData1" : "15 Apr 2021,06:43:00:pm",
"stData2" : "Wedding",
"stData3" : "kkk",
"stData4" : "100"
}
}
}
}
}
}
The only ways to get a node is by either knowing its full path, or by knowing the path to the parent node, and then some unique value under the node. Neither seems to be the case for the stData4 in your JSON, so you'll have to load the entire Wedding node and then loop over the results to get the part you want.
This isn't too bad though:
myRef = myfire.getReference("Data").child(strUID).child("Traffic/Wedding");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (!dataSnapshot.exists()) {
Toast.makeText(getApplicationContext(),"Data Not Available",Toast.LENGTH_LONG).show();
} else {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String stData1 = childSnapshot.child("stData1").getValue(String.class);
String stData2 = childSnapshot.child("stData2").getValue(String.class);
String stData3 = childSnapshot.child("stData3").getValue(String.class);
String stData4 = childSnapshot.child("stData4").getValue(String.class);
}
category basic = new category(stData1,stData2,stData3,stData4);
tvBalance.setText(stData4);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
The code above assumes that:
strUID has the value UyhzVqsz1BVFKoePa2NEmlPFu382

Why does my firebase database child return null?

I am working with firebase database and i was trying to get the value of a child using this code below and may System.out.println(MyCredit.toString()); is always returns null: Please see my firebase database
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Users");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Get map of users in datasnapshot
CollectCredits((Map<String,Object>) dataSnapshot.getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
private void CollectCredits(Map<String,Object> users) {
MyCredit = new ArrayList<>();
//iterate through each user, ignoring their UID
for (Map.Entry<String, Object> entry : users.entrySet()){
//Get user map
Map singleUser = (Map) entry.getValue();
//Get Credit field and append to list
MyCredit.add((Long) singleUser.get("Credit"));
Toast.makeText(MainActivityCustonlistViewnew.this, "Credit : " +String.valueOf(MyCredit), Toast.LENGTH_SHORT).show();
}
System.out.println(MyCredit.toString());
}
Try this:
private void CollectCredits(DataSnapshot dataSnapshot) {
MyCredit = new ArrayList<>();
//iterate through each dataSnapshot
for (DataSnapshot d1 : dataSnapshot.getChildren()){
MyCredit.add(d1.getValue());
}
}
Let me give you some suggestions, Try to check your firebase database path both the root and child path because some time you did everything correctly but the path you specified to your Database reference which is not referring to the correct path. So it can produce the same result what are getting right now.

How to query firebase database to return a value's key's parent's parent?

I am developing a team chat application . I am storing chat data in firebase.
This is my Data structure
The chats are stored under a node named chats.
each immediate child of chats is the name of a team(like whatsapp.. chat groups).
the team node have all chat messages. the chat messages are stored
with a parent node in the format timestamp_chat
My Problem
Now I have to create a firebase query to fetch this team nodes by from key.
That is
if a from: field contains the a given search value (say, "ragesh"), then the parent node "team_name" have to be returned(say,"teamrova") as a datasnapshot.
Simply speaking , I want datasnapshot of teams that have a particular username in the from field.
My Work
I tried the follwing code :
reference1 = FirebaseDatabase.getInstance().getReference().child("chats");
Query chatQuery = reference1.orderByChild("from").equalTo("ragesh");
System.out.println("Chat list :: starting");
chatQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
System.out.println("Chat list :: onChildAdded");
for (DataSnapshot chat : dataSnapshot.getChildren()) {
HashMap<String, Object> hashMap = (HashMap<String, Object>) dataSnapshot.getValue();
System.out.println("Chat list :: The chat group is =>" + dataSnapshot.getKey());
System.out.println("Chat list :: The key & Value => " + chat.getKey() +" :: "+chat.getValue().toString());
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(ChatListActivity.this, "Connection Error "+databaseError.getDetails(), Toast.LENGTH_SHORT).show();
System.out.println("Chat list :: databaseError "+databaseError.toString());
}
});
Sadly , above code don't return any value. even the
System.out.println("Chat list :: onChildAdded"); not called. And it
doesn't calls onCancelled also.(so,no error).
I get sturcked by this. please help me.
To get the username:
mRootRef.child("chats").child("teamrova").orderByChild("from").equalTo("ragesh").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot datas: dataSnapshot.getChildren()){
String name=datas.child("from").getValue().toString();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Since you are using addChildeventListener then you do not need the for loop to be able to get those values for (DataSnapshot chat : dataSnapshot.getChildren()) {
You also need to change this:
reference1 = FirebaseDatabase.getInstance().getReference().child("chats");
to this:
reference1 = FirebaseDatabase.getInstance().getReference().child("chats").child("teamrova");
The above code is an alternative with addValueEventListener

Categories