I am building my first project in android using Firebase.
I have build a Firebase's database which is having main node as post, media as its child node, media node can contain multiple values for a particular post or can have one value inside it.
So i want to fetch media child node values with particular post node.
Could you please help me out.
Any help will deeply appreciated.
Please check the screenshots below.
Firebase ref = new Firebase(YOUR_FIREBASE_URL);
String postNode ="KddShng........";
ref.child("posts/"+postNode).child("media").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.e("!_##_Key : >",dataSnapshot.getKey()); // you will get key of Media node
}
#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(FirebaseError firebaseError) {
}
});
First you need to read docs to know how to retrieve data from firebase.
and your data will be like this ...
final Firebase ref = new Firebase("URL/posts");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
//u can handle your variables name in GetData class
GetData posts = userSnapshot.getValue(GetData.class);
In another way..
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("posts");
String user_id = firebaseAuth.getCurrentUser().getUid();
databaseReference.child(user_id).child("media").getValue("user_id").getValue(etc);
You might save last line as String to reuse it anywhere.
UPDATE:
And to Fitch data You have to use Firebase adapter, example
Try something like this
FirebaseDatabase.getInstance().getReference("posts").child(UID).child("media");
Where UID is the key of the particular post node.
PS: this returns something like a promise, for which you need to attach a listener for. (because this is real time)
If just want to fetch the value once, you can do like this.
FirebaseDatabase.getInstance().getReference("posts").child("your_post_item_id").child("media").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot children : dataSnapshot.getChildren()) {
YourMediaModel mediaItem = children.getValue(YourMediaModel.class);
//add you mediaItem to list that you provided
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
Related
I want to display dayVisitors of all the dates. Hence i want to access all the dayVisitors under Noida Sec1/ all dates.Database structure
This is what I've done but it gives null pointer error: Attempt to invoke virtual method 'java.lang.String com.example.thehighbrow.visitormanagement.DayVisitor.getName()' on a null object reference.
If you want to specifically access just the dayVisitors under Noida Sec 1 you can simply implement this using:
final FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference ref = db.getReference("Noida Sec1");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
if(childSnapshot.hasChild("dayVisitor")) {
for (DataSnapshot visitorSnapshot : childSnapshot.child("dayVisitor").getChildren()) {
Visitor visitorObject = visitorSnapshot.getValue(Visitor.class); //or whatever your dayVisitor object is
//now you can access visitorObject with the fields you created and do whatever like add it to an arraylist
}
}
}
} #Override
public void onCancelled(DatabaseError databaseError) {
Log.e("READ FAILED", databaseError.getMessage());
}
});
I'm not sure what your code is doing, however, I do suggest, if possible, you try to format your database layout to be as flat as possible because nesting data in this manner can get very messy and inefficient. Maybe make dayVisitor a field in visitor rather than its own child node.
First of all get the reference to the children of Noida Sec 1 like:
DatabaseReference mNoidaReference = mFirebaseDatabase.getReference().child("Noida Sec1");
Now make a childEventListener for it and loop through it to find the dayVisitor child
ChildEventListener mChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
for(Datasnapshot data: dataSnapshot.child("dayVisitor")){
String dayVisitor = data.getValue();
}
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
mNoidaReference.addChildEventListener(mChildEventListener);
I have an android project where I retrieve data from firebase. everything is working fine but when I delete object in firebase console, it does not reflect back in the app.
Here is the link of the image:
So, suppose I delete david hafiz child node in firebase, it does not delete in the app. I have tried a lot but can't find the correct way. I am new to android programming and I hope somebody can help me. Thank You.
Update
mDatabase = FirebaseDatabase.getInstance();
mReference = mDatabase.getReference().child("Students").child("Marks");
mReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.d("value", "" + dataSnapshot);
fetchData(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return view;
}
private void fetchData(DataSnapshot dataSnapshot) {
StudentData value = dataSnapshot.getValue(StudentData.class);
Log.v("StudentData Fragment", "" + dataSnapshot.getValue());
// Get an iterator.
Iterator<StudentData> ite = mMarksList.iterator();
while (ite.hasNext()) {
StudentData iteValue = ite.next();
if (iteValue.equals(value))
ite.remove();
}
mMarksList.add(value);
Collections.sort(mMarksList, new MarksComparator());
String title = mReference.getKey();
// specify an adapter
mAdapter = new MyAdapter(getContext(), mMarksList, title);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter);
}
There are four relevant methods in ``:
onChildAdded
onChildRemoved
onChildChanged
onChildMoved
You only implemented onChildAdded, which is called in two cases:
When you first attach the listener, onChildAdded is called for each existing child.
When a child is later added, onChildAdded is called for that child.
When you delete a node from the Firebase console, the onChildRemoved method is called. But since you left that method empty, your app doesn't do anything when you remove data from the console.
To make your app behave correctly, you'll need to implement onChildRemoved. Typically this involves finding the UI element matching the snapshot and removing it.
You can store keys in order to update or remove it e.g:
ArrayList<String> mKeys = new ArrayList<String>();
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String key = dataSnapshot.getKey();
mKeys.add(key);
adapter.notifyDataSetChanged();
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
String key = dataSnapshot.getKey();
int index = mKeys.indexOf(key);
mMarksList.remove(/*index*/); // or data
adapter.notifyDataSetChanged();
}
You might be interested how to update too.
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.
Here is my firebase structure
Here is my code fore the firebase
final FirebaseDatabase database = FirebaseDatabase.getInstance();
bookingRef = database.getReference("booking");
query = bookingRef.orderByChild("studentID").equalTo("S00001");
query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Booking myBooking = dataSnapshot.getValue(Booking.class);
addBookingRow(myBooking, dataSnapshot.getKey());
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
//here it is fired when the alarset value is changed
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
String tag = dataSnapshot.getKey();
removeBookingRow(tag);
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Each Booking node has several child nodes(?) which are classID, studentID, attended, alarmType
As you can see, I have got query for getting nodes having certain student ID.
Then, i have added addChildEventListener for the ordered nodes.
So, when any of the child nodes of the booking node changes, the onChildChanged method is fired, and it gives me the data snapshot for the booking node having child node change.
Here I want to know what child node changed. Like I want to know if the onChildChanged method is fired on the change of ClassID.
It is because I want to implement different behaviour based on change of each child node
Do i have to set some listener for each child node? or ..
Can you guys give me solutions?
I am developing in android studio
thanks