I am currently building an app in Firebase and I want to get all the users parking spaces but the problem is that my code doesn't retrieve parking spaces child of each user from firebase, it doesn't get any data.
This is my code:
public ArrayList<ParkingSpace> retrieve() {
db.child("Users").child("Parking Spaces").orderByChild("adress").equalTo("park1").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
...
};
}
private void fetchData(DataSnapshot dataSnapshot) {
ParkingSpace space = dataSnapshot.getValue(ParkingSpace.class);
space.setId(dataSnapshot.getKey());
parkingsSpaces.add(space);
}
This is the tree:
db.child("Users").child("Parking Spaces").orderByChild("adress").equalTo("park1")
This code will retreive each parking space with value = "park1".
Whereas your parkingSpace values are objects with inner attributes. I don't think Firebase provide ways to retreive them directly by filtering by their attribute.
You have to filter the response inside your application:
public ArrayList<ParkingSpace> retrieve() {
db.child("Users").child("Parking Spaces").orderByChild("adress").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
...
};
}
private void fetchData(DataSnapshot dataSnapshot) {
ParkingSpace space = dataSnapshot.getValue(ParkingSpace.class);
if ( "park1".equals(space.getAdress)) {
space.setId(dataSnapshot.getKey());
parkingsSpaces.add(space);
}
}
Related
My Firebase Database is being accessed twice, once for Feed_modell and another for Book and showing duplicate data, how can I fetch Firebase data from different models (Book and Feed_modell) one time in a List.
I tried to fetch data from the Feed_modell model and then the Book template, but my Firebase fetch the 4 data into the Feed_modell and then again the same four data into the Book.
private RecyclerViewFeedAdapter Adapter;
private List<Object> feedList;
private void loadtheFeed() {
feedList.clear();
dbs = FirebaseDatabase.getInstance().getReference("feedPosts");
Query query = dbs.child(feedReceivingKey);
childEventListener1 = query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Feed_modell post = dataSnapshot.getValue(Feed_modell.class);
Book book = dataSnapshot.getValue(Book.class);
feedList.add(post);
feedList.add(book);
Adapter.notifyDataSetChanged();
}
#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) {
}
});
}
Read my Firebase once for both models.
I have a problem with my code, I don't know if I get it because of onChildAdded or RecyclerView
Simply I want to display messages Inbox on RecyclerView that contains all messages I received from other users, each message contains the last message sent and information about senders such as his name and photo.
Like this
This is my structure
Messages
Receiver_UID
Sender_UID
push
message : "text"
I used 2 nested query to achieve that
so firstly I get sender UID, and then I get the last message from another query
dataQuery = FirebaseDatabase.getInstance().getReference("Messages").child(my_Id);
dataQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot getalldata, String s) {
final String sender_UID = getalldata.getKey();
Query lastmess = FirebaseDatabase.getInstance().getReference("Messages").child(my_Id).child(sendUID);
lastmess.orderByKey().limitToLast(1).addChildEventListener(new ChildEventListener() { // last message
#Override
public void onChildAdded(DataSnapshot snap, String s) {
MessModel messages = snap.getValue(MessModel.class);
String Last_message = messages.getMessage();
getUserData(Last_message ,sender_UID);
}
#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) {
}
});
}
#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) {
}
});
And finally I get information of sender by this method
private void getUserData(final String last_message , String sendUID) {
FirebaseDatabase.getInstance().getReference("Users").orderByKey().equalTo(sendUID).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(final DataSnapshot data, final String s) {
listImessagesitem model = data.getValue(listImessagesitem.class);
name =model.getName();
uid = model.getUid();
//another information
result.add( new listImessagesitem( name ,last_message ,uid, ... another info));
useradapter = new listMessagesAdapter(getActivity(),result);
myList.setAdapter(useradapter);
useradapter.notifyDataSetChanged();
}
#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) {
}
});
}
It works well the first time and when I make refresh as well
The problem is when someone, in the list of messages Inbox, sends me a new message. In this case, if I didn't make refresh, I see two senders with the same information and different last messages ... If he sent again, I see 3 senders with same previous case and so on.
How can I fix it?
I mean How can I add the new message to the user if he already exists in my inbox list
Any help would be appreciated, Thanks
What I understand from looking at your code is that u have nested ChildEventListener's. So every-time the top listener is invoked a new inner child listener is created causing duplicate data as it calls the getUserData method to update the adapter.
What you can do?
1: Check if the result list contains the object if not then add otherwise ignore.
2: From what I understand, I believe you are trying to create a Mail Client application where two users are sending emails to each other. So instead of the structure that you have in your db why not create a single node for both the users something like this user_1_ID+user_2_ID .
This reduces the complexity as both the users will read from the same node and the message object should have a timestamp field to determine the latest message.
My structure is like following
- Posts
- keu23jndf
- dateTime:"2376464"
- name:"abc"
- key34njf
- dateTime:"4333434"
- name:"xyz"
Now, I want to retrieve sorted data by dateTime in descending order.
Thanks
Ok so first of all I would suggest you to not use a client sided timestamp but instead use the ServerValue.TIMESTAMP. In most cases this is going to be the better setup. If you know what you are doing and you want it exactly like that, forget this and just read on.
The problem if you want to sort from newest to oldest is that Firebase does (as far as I know) not support this.
A workaround would be to use the negative value of the Firebase ServerValue.TIMESTAMP.
This is how I do it. It may not be the perfect or right way, but it does work
private void prepareUpload() {
//mDatabase is a reference to the root of the Firebase Database
final DatabaseReference timestampReference = mDatabase.child("timestamp");
final String timestampKey = timestampReference.push().getKey();
timestampReference.child(timestampKey).setValue(ServerValue.TIMESTAMP);
timestampReference.child(timestampKey).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
Long timestamp = 0 - Long.parseLong(dataSnapshot.getValue().toString());
upload(/*Starting upload with new timestamp here (this is just a dummy method)*/);
timestampReference.child(timestampKey).removeValue();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, databaseError.getMessage());
}
});
}
Now you have to set your Firebase Database rules as follows:
"Posts": {
".indexOn" : "date",
...
}
Finally you just have to query your 'Posts' somehow like this:
mDatabase.child("Posts").orderByChild("dateTime").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//Do stuff with your data
}
#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) {
}
});
Hope this helps!
I'm using Firebase database and I'm retrieving data from it. When my database has data, addChildEventListener working well but when my database hasn't data, addChildEventListener not working. Bellow, this is my code:
mDatabase = FirebaseDatabase.getInstance().getReference().child("music");
public void getListMusicFromFirebase() {
mDatabase.addChildEventListener(this);
}
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
updateMusic(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
updateMusic(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
updateMusic(dataSnapshot);
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
private void updateMusic(DataSnapshot dataSnapshot) {
mListMusic.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
String title = snapshot.getValue(Music.class).getTitle();
String artist = snapshot.getValue(Music.class).getArtist();
String year = snapshot.getValue(Music.class).getYear();
String duration = snapshot.getValue(Music.class).getDuration();
String uri = snapshot.getValue(Music.class).getUri();
Music music = new Music(title, artist, year, duration, uri);
mListMusic.add(music);
}
if (mListMusic.size() > 0) {
bindingListMusic();
return;
}
mBinding.tvDataEmpty.setText("No data");
mDialog.dismiss();
}
I check my list. If size of it greater than 0, I will bind it to recyclerview and opposite, I will notify it haven't data, it working well when having data but when I delete all data from Firebase database, my code can't perform updateMusic() method.
Please help.
To initiate your listener you should have the required data in your firebase database. AddChildEvent listener requires a predefined parent where you will attach it on app launch(or whenever you want) . If there is no parent the listener will never be attached or initiated.
This will result in no response when you later add a parent and add childs to it. So, always make sure that the parent to which you adding childEventListener is already present and the value is not null.
Hope this helps.
How to handle onChildAdded event in firebase android.
below is my database json structure
{
message{
"id"=10;
"name"="xyz"
}
}
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
// how can I handle the particular child that has added
}
this method triggers when a new child is added to my reference node. But how can I get the value for the particular child with out typecasting
The child added is the one returned on the dataSnapshot. So, if you want to get it's key:
String myKey = dataSnapshot.getKey()
For the value:
String myKey = dataSnapshot.getValue(String.class)
For the value you need to define the type you are expecting. On this example I specified that a String is expected, but you can even cast the value to any object you are using (as long as the fields match on your object model and on the dataSnapshot):
User myUser = dataSnapshot.getValue(User.class)
For more details please go to the Firebase official documentation.
In reference, add your app firebase console url.
DatabaseReference myFirebaseRef = database.getReference("Your firbase path");
myFirebaseRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if(dataSnapshot.hasChild("message")) {
for (DataSnapshot poly : dataSnapshot.child("message").getChildren()) {
String id=String.valueOf(poly.child("id").getValue);
String name=String.valueOf(poly.child("name").getValue);
}
}
}
#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) {
}
});
You will need a model class as per the child nodes and entities you have in your database.
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
ModelClass model = dataSnapshot.getValue(ModelClass.class)
//assuming this is used for list of data..
list.add(model);
}
Child Event Listener does not crash even if the child nodes are not available or not yet created dyanamically.You also won't need any loop for moving to the next node.
If you want to get just a specific child value then do this
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if(dataSnapshot.hasChild("name")){
String name = dataSnapshot.child("name").getValue().toString();
}
}