How to retrieve particular nodes in Firebase Realtime Database? - android

I'm making a post app with Firebase Realtime Database.
The app needs a bookmark function, but I don't know how to load the bookmarked (selected) post.
Database structure:
Code:
databaseReference = databaseReference.child("post").child(getLen()).child("all-posts").child("-KYbMBatKdoWYw45-2pp").child("bookmarkUsers").orderByChild(myUserId).equalTo(myUserId);
but this code is not working. Why doesn't it work? I think that it only returns bookmarkUsers child node.
Do I have to make another node only for bookmark?
I already made a node only for bookmark, but I could't manage bookmardCount and starCount synchronization.
Thanks!

DatabaseStorage Posts=FirebaseDatabase.getInstance().getReference().child("posts");
Posts.child("0").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot DS: dataSnapshot)
{
//Get all other Values Except bookmarkusers and store them
String POST_NAME = dataSnapshot.getKey();
Posts.child("0").child(POST_NAME)addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshotf) {
for(DataSnapshot BOOK: dataSnapshotf)
{
//Collect all BookMarks and store them
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Do I have to make another node only for bookmark?
Yes, you do. To get more information, read about structuring you data in firebase here.
I already made a node only for bookmark, but I could't manage bookmardCount and starCount synchronization.
You will need to keep the bookmarkCount and starCount inside the post node itself.

Related

Retrieve Firebase data who have specific child

Please check my database image. I want to select and display all users who have parent = chris
my database image
To retrieve the users that contain parent : chris, you can do the following:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("users");
reference.orderByChild("parent").equalTo("chris").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot datas: dataSnapshot.getChildren()){
String name = datas.child("name").getValue(String.class);
String key = datas.getKey();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
orderByChild.equalTo is a query that will retrieve all the nodes that contain parent equal to chris.
Since you tagged this as a android studio question I assume you are using the Firebase SDK.
You should check out the documentation, where they explain how you can query in a lot of languages with very nice examples.

How to retrieve data from a list of children that I don't know the name of in advance?

Hi I am very new to Firebase and Java and I am looking for a hopefully easy answer. This is my database:
In my code the user inputs a name and number from separate text fields. I use the name to generate a child in "Client." What I want to do is take the "Name" and "Number" values and output them into text on my application. Problem is I am having a hard time figuring out how to reference the children of Client to output the data. Alex, David, Will are just placeholders for really any value the user inputs so how do I reference a child I don't know the name of?
First retrieve your Client datasnapshot
//Get datasnapshot at your "users" root node
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Client");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Get map of users in datasnapshot
collectInfo((Map<String,Object>) dataSnapshot.getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
Then loop through clients, accessing their map
private void collectInfo(Map<String,Object> clients) {
//iterate through each client
for (Map.Entry<String, Object> entry : clients.entrySet()){
//Get client map
Map singleClient = (Map) entry.getValue();
// Do whatever you want to do with single clients
}
}
Here's a simple way:
DatabaseReference clientsRef = FirebaseDatabase.getInstance().getReference().child("Client");
clientsRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot clientSnapshot: dataSnapshot.getChildren()) {
System.out.println(clientSnapshot.getKey()); // "Alex", "David", "Will"
System.out.println(clientSnapshot.child("Name").getValue(String.class)); // "Alex", "David", "Will"
System.out.println(clientSnapshot.child("Number").getValue(String.class)); // "12345", "98765", "12345"
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
If you are just getting started with Android development and Firebase, I recommend taking this codelab first. It will save you much time (and questions) going forward.

Need to restructure JSON database or make single query(Firebase)

I have 2 branches in my JSON tree, which look like this:
users {
profile-data {
user-key {
//here is users profile fields like nickname and other
}
......
}
friends {
user-key {
friend's-user-key:true
another-friend's-user-key:true
......
}
}
}
The problem is to fetch all users-profile data of users, that are friends of any user. I didn't find the way to fetch all this data by 1 query so I need to write something like this:
usersFriendsRef.child("userId").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
String userId = child.getKey();
usersProfileDataRef.child(userId).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
////Only here i can get user's profile data
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
So the problem is that I need to make many requests to fetch friends' profile data one by one, so I need to restructure my database or find the way to write this as 1 query
That's the correct way in which you can achieve this. There's no problem with nested queries. You need to find all those id's and then based on them, to query. I could move the friends node under profile-data -> user-key to create a single query but knowing that in Firebase is best to have the data as flatten as possible, it's not a solution.
Keep in mind not to forget to remove the listener, when it's no more needed, like this:
databaseReference.removeEventListener(valueEventListener);
Hope it helps.

How to modify an specific value in Firebase?

I have this data in Firebase Database:
Negocios:
-KjfCu56lFZCybYldBZy
lugarReference: "Restaurante"
numeroMesas:39
password:"pass123"
user:"user123"
user_id:"usr_1"
I have two applications connected to one project in Firebase, one of them upload data of restaurants reservation, and the other one displays reservations in a RecyclerView.
In the first application, once I do a reservation, it must minus one to numeroMesas value, the other application should display any changes to this key.
In the reservation application, I have this piece of code that I did base in this question:
Update specific keys using Firebase for Android
It supposes to modify the value of numeroMesas, but it does not:
mReference.child("Negocios").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot : dataSnapshot.getChildren()){
Lugar lugar = postSnapshot.getValue(Lugar.class);
if(nombre_lugar.equals(lugar.getUser_id())){
DatabaseReference numMesasReference = mReference.child(dataSnapshot.getKey()).child("numeroMesas");
numMesasReference.setValue(lugar.getNumeroMesas() - 1);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
What it does is the next thing:
Negocios:
-KjfCu56lFZCybYldBZy
lugarReference: "Restaurante"
numeroMesas:39
password:"pass123"
user:"user123"
user_id:"usr_1"
-Negocios
-KjfCu56lFZCybYldBZy
numeroMesas:39
How can be fixed?
I need to minus one once I do a reservation...
Greetings!
Using postSnapshot.getRef() you obtain a reference to the source location for this snapshot. So what's next is to add a child to that reference, that reference will be "numeroMesas" that is the key you want to modify.
As easy as that, the code will be like this.
mReference.child("Negocios").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot : dataSnapshot.getChildren()){
Lugar lugar = postSnapshot.getValue(Lugar.class);
if(nombre_lugar.equals(lugar.getUser_id())){
DatabaseReference numMesasReference = postSnapshot.getRef().child("numeroMesas");
numMesasReference.setValue(lugar.getNumeroMesas() - 1);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
P.S: If you want to minus one just once by reservation, addValueEventListener() won't work, it will minus multiple time as a loop. Use addListenerForSingleValueEvent() instead addValueEventListener().
As the name says, this listener fits for single changes in the data at any location.
I guess the problem is with dataSnapshot.getKey() in this line
DatabaseReference numMesasReference = mReference.child(dataSnapshot.getKey()).child("numeroMesas");
Here you getting the key for the whole list of Negocios, not for the specific child replace it with `
postSnapshot.getKey()
The problem is that your DatabaseReference that you are using is wrong. You are missing a child. So in order to solve this problem, please use the following code:
mReference.child("Negocios").child(negociosId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int numeroMesas = (int) dataSnapshot.child("numeroMesas").getValue();
if(nombre_lugar.equals(lugar.getUser_id())){
mReference.child("Negocios").child(negociosId).child("numeroMesas").setValue(numeroMesas - 1);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
In which negociosId is the unique id generated by the push() method.
Hope it helps.
I'm new to firebase and android. But If the above solutions doesn't work please do the following. I think the problem is that you didn't convert the value of numeroMesas to string. Sorry if there's anything wrong.
Hope it helps.
mReference.child("Negocios").child(negociosId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(nombre_lugar.equals(lugar.getUser_id())){
mReference.child("Negocios").child(negociosId).child("numeroMesas").setValue((Integer.parseInt(dataSnapshot.child("numeroMesas").getValue().toString())) - 1);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});

How to retrieve all objects from a Node in Firebase database?

I followed the documentation, but no matter what, I cannot figure out how to return all the objects from a single node. For example, I want to return a list of all company objects from the companies node. Once I have that list, I want to parse them all into JSON objects. This is my first time with a NoSQL database so I'm sure that I'm missing something small.
Currently I have:
DatabaseReference companiesRef = FirebaseDatabase.getInstance().getReference("12265");
companiesRef.child("companies").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("Count ", dataSnapshot.getChildren().toString());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
But it just returns null for the value: DataSnapshot { key = companies, value = null }.
Here's my database:
You create your reference like this:
FirebaseDatabase.getInstance().getReference("12265");
This means that Firebase looks at the root of the database and returns the child 12265 from under there. It does not automatically search the tree for a node with a matching name.
So you'll need to specify the entire path:
FirebaseDatabase.getInstance().getReference("android/users/12265");
Don't add any parameters to your getReference() (let it go to the root of database) and then set the addListenerForSingleValueEvent. And you have not used getvalue() on you datasnapshot as well. Try this code:
DatabaseReference companiesRef = FirebaseDatabase.getInstance().getReference();
// this is the patch that I see from the image that you have attached.
companiesRef.child("telenotes").child("android").child("user").child("12265").child("companies").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("Count ", dataSnapshot.getChildren().getValue().toString());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Categories

Resources