From this I want take the value of email from mailID and subject, title from mailText.i'm able to access the value of single child but when it show null with when try get with all three.
Following code working for single child:
DatabaseReference databaseRef = database.getReference("/");
databaseRef.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<String> email = new ArrayList();
for (DataSnapshot sd: dataSnapshot.getChildren()) {
String emailStr = sd.child("email").getValue(String.class);
email.add(emailStr);
System.out.println(email);
}
latch.countDown();
}
Above code gives me array contain the all email like that i want to take value of email,title and subject.
Assuming that the new node is a direct child of your Firebase root, to achieve what you have explained in your comments, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference newRef = rootRef.child("new");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.child("mailID").getChildren()) {
String email = ds.child("email").getValue(String.class);
String name = ds.child("name").getValue(String.class);
Log.d("TAG", email + " / " + name);
}
for(DataSnapshot ds : dataSnapshot.child("mailText").getChildren()) {
String title = ds.child("title").getValue(String.class);
String subject = ds.child("subject").getValue(String.class);
Log.d("TAG", title + " / " + subject);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
newRef.addListenerForSingleValueEvent(valueEventListener);
As you see, you need to attach a listener one step higher in your tree hierarchy and to loop throught the children using getChildren() method twice.
You need to change the database structure(there is no join in firebase), to be able to query and get the required data:
new
mailId
email: userx#gmail.com
name:userx
title: test title
Body: test body
Then you will be able to retrieve the required data for the user.
You can also use Queries to be able to get the related data, example:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("new");
ref.orderByChild("email").equalTo("userx#gmail.com");
Related
I'm having trouble with snapshot being able to print the values, but being specific by using get values returns null.
I'm trying to retrieve the the list uploaded in Firebase and compare it to the list that the user will pass.
rootReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot item_child : snapshot.getChildren())
{
String recId = item_child.getKey();
DatabaseReference rootReference = FirebaseDatabase.getInstance("https://what-s-cookin-a3bec-default-rtdb.asia-southeast1.firebasedatabase.app/")
.getReference().child("Recipes").child(recId);
Log.d(TAG, "RECID: " + recId);
rootReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren())
{
Log.d(TAG, "SNAPSHOT: " + ds);
Log.d(TAG, "SPECIFIC: " + ds.child("ingredients"));
if(ds.child("ingredients").getValue() != null)
{
Log.d(TAG, "INGREDIENTS NOT NULL");
ArrayList<String> ing = new ArrayList<String>();
for (DataSnapshot ings : snapshot.child("ingredients").getChildren())
{
ing.add(ings.getValue(String.class));
Log.d(TAG, "DS: " + ds);
Log.d(TAG, "INGS: " + ings);
}
This is the result from logcat:
SNAPSHOT: DataSnapshot { key = ingredients, value = {0=Fish, 1=bitter, 2=cilantro} }
SPECIFIC: DataSnapshot { key = ingredients, value = null }
Logcat screenshot
This is our firebase:
Firebase Screenshot
Recipes
1634971267099
favCount: 8
id: "1634971267099"
imageUrl: "https://firebasestorage.googleapis.com/v0/b/wha..."
ingredients
0: "Fish"
1: "bitter"
2: "cilantro"
mainIng: "Pork"
measure: "test"
name: "Pochero"
prod: "test"
serve: "15"
time: "30"
uid: "tMdUFcAelyeVo5DYW3P7HolRW4S2"
Check your code is matching with Firebase data.
It would be more clear if you post screenshot of Firebase data to understand the database hierarchy.
Its difficult to understand the database structure from your code.
So I am working on the memories Firebase app and there is a stage where the user can upload photos to his memory. Each photo has uniq name "ImgLink0","ImgLink1",etc..
The function I am working on is to delete a specific photo when I am pressing a long click, but I can't reach the image in Firebase.
I tried like below but I got stuck because I can't identify the image key:
mDatabase.child(userUID).child("Memories").child(memoryName).child("Images").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot imageSnapshot : dataSnapshot.getChildren()) {
String imagesKey = imageSnapshot.getKey();
String imagesValue = (String) imageSnapshot.getValue();
Log.e("Test","" + imagesKey + "" + imagesValue);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
And this is the data structure:
I tried using query too but with no success because I don't have the image key.
Thank you for any help :)
To delete a node from the database, you need to know the completely path to that node.
Assuming you do know the URL of the image to delete, but not the key (ImgLink1 or ImgLink2) that is stored under, you're going to have to use a query to look up that key.
Something like:
DatabaseReference ref = mDatabase.child(userUID).child("Memories").child(memoryName).child("Images");
Query query = ref.orderByValue().equalTo("URL of the image")
query..addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot imageSnapshot : dataSnapshot.getChildren()) {
imageSnapshot.getRef().removeValue();
}
}
...
Also see these related answer:
deleting specific post in database(by post node) but it deletes entire database_table
How can i remove all fields and values by using key value or a field key from firebase realtime database?
To remove the second URL for example, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference imageToDeleteRef = rootRef
.child(uid)
.child("Memories")
.child("TestMem")
.child("Images")
.child("ImgLink1");
imageToDeleteRef.removeValue().addOnCompleteListener(/* ... */);
So I have created a reference that points exactly to ImgLink1 node and then I called .removeValue() on reference in order to delete it. So there is no need to read the value in order to perform a delete operation.
If you want to read the URL, please use these lines:
imageToDeleteRef.addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
String url1 = task.getResult().child("ImgLink1").getValue(String.class);
Log.d("TAG", url1);
} else {
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
The result in the logcat will be:
https://firebasestorage.googleapis.com...
I am working on my login screen.
However, when I run the code after filling both ID and pw, the userId (code below) is still null.
foundUser = dataSnapshot.getValue(User.class);
userId = foundUser.getId();
userPw = foundUser.getPw();
My application is definitely connected to the Firebase. However, when I debug the code, I can see
W/ClassMapper: No setter/field for exampleuserID found on class com.example.hellobook.User
Shouldn't this
for (DataSnapshot ds : dataSnapshot.getChildren()) {
foundUser = dataSnapshot.getValue(User.class);
be
for (DataSnapshot ds : dataSnapshot.getChildren()) {
foundUser = ds.getValue(User.class);
You have put wrong Reference of Database.
DatabaseReference ref = database.getReference().child("hellobookdatabase").child("User").child(id);
Now you need make little changes in your Condition.
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
foundUser = dataSnapshot.getValue(User.class);
userId = foundUser.getId();
userPw = foundUser.getPw();
if (userId!=null && userId.equals(id)) {
if (userPw.equals(psw)) {
startActivity(new Intent(LoginScreen.this, LandingScreen.class));
}
}
else {
Toast.makeText(LoginScreen.this, "Wrong ID or password. Try again", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled (DatabaseError error) {
#NonNull DatabaseError databaseError; }
});
The reason Why your query not working :
Your reference wasn't proper.
Your valueEventlistener was searching user id in hellobookdatabase instead of User child.
Any other query related to this just Comment down.
Try
Change this
DatabaseReference ref = database.getReference("User")
Query sqlite = mDatabaseReference.child("Messages").child(MessageSenderId).child(MessageRecieverId);
sqlite.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("Message")) {
String msg = dataSnapshot.child("Message").getValue().toString();
String from = dataSnapshot.child("From").getValue().toString();
String time = dataSnapshot.child("Time").getValue().toString();
} else {
Toast.makeText(getApplicationContext(), "NULLLL", Toast.LENGTH_SHORT).show();
}
Database
This is the most basic thing in the database. I have never got a problem with childEvent or valueEvent and i want a single event for now and I'm not able to fetch.
There is no error because i have put an if statement and it shows toast as null which means dataSnapshot doesn't have a child named messages but it's right there. I tried putting a for loop too, but didn't work
You have not given the full reference. There is a list of push keys and you have to use a foreach loop.
Query sqlite = mDatabaseReference.child("Messages").child(MessageSenderId).child(MessageRecieverId);
sqlite.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot vinSnapshot : dataSnapshot.getChildren()) {
if (vinSnapshot .hasChild("Message")) {
String msg = dataSnapshot.child("Message").getValue().toString();
String from = dataSnapshot.child("From").getValue().toString();
String time = dataSnapshot.child("Time").getValue().toString();
} else {
Toast.makeText(getApplicationContext(), "NULLLL", Toast.LENGTH_SHORT).show();
}
}
Or you can store all data into ArrayList then perform your task.
I have to receive a username that has a fullName equal to "Bobby". So I'm trying to get data from Firebase Database using the following syntax:
ref.orderByChild("fullName").equalTo("Bobby").addListenerForSingleValueEvent(new ValueEventListener() {...}
What I get from dataSnapshot.getValue() is this:
{id3={username=bob, score=150, fullName=Bobby}}
I would like to know what is the best or correct way to get the username if I do not know which id number was returned?
Currently I'm achieving it this way:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("Scores");
ref.orderByChild("fullName").equalTo("Bobby").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.i(TAG, "dataSnapshot value = "+dataSnapshot.getValue());
if(dataSnapshot.hasChildren()){
Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator();
DataSnapshot snap = iter.next();
if(snap.hasChildren() && snap.getValue() instanceof HashMap) {
HashMap map = (HashMap) snap.getValue();
if(map.containsKey("username")) {
Log.i(TAG, "onDataChange: username = " + map.get("username"));
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
EDIT:
The Database structure is looking like this:
{
"Scores" : {
"id1" : {
"fullName" : "Robert",
"score" : 96,
"username" : "rob"
},
"id2" : {
"fullName" : "Michael",
"score" : 87,
"username" : "mike"
},
"id3" : {
"fullName" : "Bobby",
"score" : 150,
"username" : "bob"
}
}
}
Thanks in advance.
SUMMARY:
Using wilkas' answer I came to the following code snippet to get the wanted result:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("Scores");
ref.orderByChild("fullName").equalTo("Bobby").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.i(TAG, "dataSnapshot value = "+dataSnapshot.getValue());
if(dataSnapshot.hasChildren()){
Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator();
while (iter.hasNext()){
DataSnapshot snap = iter.next();
String nodId = snap.getKey();
String username = (String) snap.child("username").getValue();
//received results
Log.i(TAG, username + " on nod " + nodId);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
It works well when several entries have a fullName equal to 'Bobby'.
Since you add listener under Scores, your childs are id1, id2 and id3. By adding query .orderByChild("fullName").equalTo("Bobby") you filter by subchild and get one result id3. So your first datasnapshot refers to one child id3 (though there could be more children if they would have same name of "Bobby").
In order to get the username, you need to iterate each received child (as you correctly do) - in this case only one child is iterated - and then get child username of that iterated child.
Since you know that every idX contains these children: username, score, fullName. You can easily extract username as follows (in your case snap is reference to child id3):
String username = (String) snap.child("username").getValue();
String fullName = (String) snap.child("fullName").getValue();
long score = (long) snap.child("score").getValue();
Furthermore you can retrieve id too as follows:
String recordId = snap.getKey();
Within the inner iteration you could also get username as follows:
String recordId = snap.getKey();
String username = (String) dataSnapshot.child(recordId).child("username").getValue();