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...
Related
I have a root node named 'Posts'. Then each node inside Posts has a unique postID generated by push(). Now each post has several children. One such child is "saves" in which I have stored the userIDs of those users who have saved this particular post. What I want to do is that I want to create and display a list of all those posts which a particular user has saved.
This means that I have to write a code that will scroll through all posts in 'Posts' node, check for 'saves' child in each post,
if it exists, then check for userID of a particular user in 'saves',
if it exists, then that post should be added to a list called 'mySavedPosts'.
Please click here to see the structure of my 'Posts' node.
I have tried many different ways to achieve this but I am just getting an empty list or app crashes. I cannot post all the different ways that I have tried since that would make this question very lengthy and clumsy, but all my ways revolve somewhere around this approach:
FirebaseDatabase.getInstance().getReference()
.child("Posts")
.child("saves")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
mySavedPosts.clear();
if (snapshot.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).exists()){
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
Post post = dataSnapshot.getValue(Post.class);
mySavedPosts.add(post);
}
}
Collections.reverse(mySavedPosts);
postAdapterSaves.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
I have also tried entering .child(post.getPostID()) after .child("Posts") but that generates a null Pointer Exception.
I have also tried entering .child(auth.getUid()) after .child("saves"), that didn't work too!
I have tried 10s of other modifications but none of them have worked.
According to your comment:
I just need to see if the auth.getUid() is there in the children of "saves".
To check if the UID of the authenticated user exists in the "saves" node, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference postsRef = rootRef.child("Posts");
Query query = postsRef.orderByChild("saves/" + uid).equalTo(true);
query.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot postSnapshot : task.getResult().getChildren()) {
Post post = postSnapshot.getValue(Post.class);
mySavedPosts.add(post);
}
Collections.reverse(mySavedPosts);
postAdapterSaves.notifyDataSetChanged();
} else {
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
I want to reach projectImageUrl but the problem is in between Projects and project Image URL there is a random key for each project so that each project should have a unique name, So how can I reach to projectImageUrl?
How can I access to a node in Firebase who has a random key?
That's not actually random. As I see in your database schema, you are using as the key for the User object, the value of the UID which is concatenated with the date and time. Both date and time, are already apart of the User object. Adding them along with the UID is really not necessary because the UIDs are already unique. There is no need to add anything else to make it "more" unique. My recommendation is to only use the UID and nothing more. In that case, to get the URLs that exist under the projectImageUrl node, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference projectImageUrlRef = rootRef.child("Projects").child(uid).child("projectImageUrl");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String url = ds.getValue(String.class);
Log.d("TAG", url);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
projectImageUrlRef.addListenerForSingleValueEvent(valueEventListener);
The result in the logcat will be the URLs that exist under projectImageUrl node. If you need to keep the date and time, please change the projectImageUrlRef to:
DatabaseReference projectImageUrlRef = rootRef.child("Projects").child(uid + date + time).child("projectImageUrl");
Where that date should hold the value of "06-Oct-2020" and the time "16:37:9".
I'm currently building a to-do app on Android Studio. I'm facing an issue with my Firebase database. What I'm trying to do is, each user to have a unique id based on their google sign in, in order to see only their own data. Currently, on my app, everyone can see anyone's' tasks. On Firebase I'm using the Realtime Database, specifying it by one child of "Users" and another one of Task + a random number. Also, I've already added the google sign in button on the launch of my app.
Current Database:
enter image description here
Example of how my hierarchy wants to be:
enter image description here
According to your comments, to get only the Task objects the correspond to a particular user, please use the following lines of code:
String userId = "User-13294";
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference tasksRef = rootRef.child("Users").child(userId).child("Tasks");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot taskSnapshot : dataSnapshot.getChildren()) {
String title = taskSnapshot.child("title").getValue(String.class);
Log.d("TAG", title);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
tasksRef.addListenerForSingleValueEvent(valueEventListener);
Because User-13294 has only one Task, the result in the logcat will be only one title:
Swimming
I am familiar with firestore but uncertain how to get the values from realtime database. here is my database below
data base image
As u can see I have UID under which I have stored multiple document references. here how I did:
firebaseDatabase.getReference(firebaseAuth.getCurrentUser().getUid()).push().setValue(documentReference.getPath());
I want to get the whole document references under the UID and store it in an array list or just iterate through each document reference. Thank you
Try below.
DatabaseReference mDatabaseRef = FirebaseDatabase.getInstance().getReference(firebaseAuth.getCurrentUser().getUid());
ArrayList<String> docRefList =new ArrayList<>();
mDatabaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
String docRef = postSnapshot.getValue(String.class);
docRefList.add(docRef);
}
}
#Override
public void onCancelled(DatabaseError error) {
Log.d(TAG, "Error Load");
}
});
Remember that onDataChange() is an async call to read from Firebase DB. Therefore, for any post processing of data you receive, you have to wait until the data read is completed.
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");