I am trying to fetch recently added messages from database. But whenever I fetch those messages all messages are shown in recyclerview. I just want to show recently added messages.
//Here is my code -
mFirebaseDatabase = FirebaseDatabase.getInstance();
mDbReference = FirebaseDatabase.getInstance().getReference();
final DatabaseReference uidRef = mDbReference.child("users").child(currentUser).
child(selectedUser).child(ChatMessageModel.MSG_TYPE_RECEIVED);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ChatMessageModel chatMessageModel = ds.getValue(ChatMessageModel.class);
messageList.add(chatMessageModel);
}
chatAppMsgAdapter.notifyDataSetChanged();
mRecyclerview.setAdapter(chatAppMsgAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, "onCancelled: ");
}
};
uidRef.addValueEventListener(valueEventListener);
//here output like this -
enter image description here
Edit: Added Explanations
By using the reference in uidRef, you are retrieving all the data in that node of the firebase path.
To retrieve the last data added to that node in the database, you should add .limitToLast(1) method.
Check Firebase Query - limitToLast()
Also, since you're retrieveing only one datum, you don't need to iterate, hence the removal of the forEach loop.
mFirebaseDatabase = FirebaseDatabase.getInstance();
mDbReference = FirebaseDatabase.getInstance().getReference();
final DatabaseReference uidRef = mDbReference.child("users").child(currentUser).
child(selectedUser).child(ChatMessageModel.MSG_TYPE_RECEIVED);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
ChatMessageModel chatMessageModel = ds.getValue(ChatMessageModel.class);
messageList.add(chatMessageModel);
chatAppMsgAdapter.notifyDataSetChanged();
mRecyclerview.setAdapter(chatAppMsgAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, "onCancelled: ");
}
};
// Add the .limitToLast(1) query function or replace with the
// limitToFirst(1) if .limitToLast(1) didn't work
uidRef.limitToLast(1).addValueEventListener(valueEventListener);
Related
I need some help.
I have a realtime database in firebase. I need to bring all records from this table.
After already setting the connection, I tried the command:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("rlmb-loterias");
I need the whole contents of the table and generate an array or a json
first you have to get all the keys and then you can get table values like this :-
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("rlmb-loterias");
usersRef .addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snap : dataSnapshot.getChildren()){
usersRef.child(snap.getKey()).addListenerForSingleValueEvent(new
ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String data = dataSnapshot.getValue();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
//enter code here
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
//enter code here
}
});
In order to get the keys and the corresponding values, you need to attach a listener on your reference. Assuming that the rlmb-loterias node is not your root node, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference rlmbLoteriasRef = rootRef.child("rlmb-loterias");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String key = ds.getKey();
String value = ds.getValue(String.class);
Log.d(TAG, key + " / " + value);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
rlmbLoteriasRef.addListenerForSingleValueEvent(valueEventListener);
If your rlmb-loterias node is your root key, then simply attach the listener on the rootRef:
rootRef.addListenerForSingleValueEvent(valueEventListener);
I am writing to the realtime database in a method using
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Test");
myRef.setValue("test");
Database structure
Later on I am trying to retrieve this string in another method using
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Test");
ValueEventListener valueEventListener = myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
value = dataSnapshot.getValue(String.class);
}
#Override
public void onCancelled(DatabaseError error) {
}
});
I want value to read "test" but it always returning null.
Use this technique to resolve your issue
mRef=FirebaseDatabase.getInstance().getReference().child("Test")
ValueEventListener listener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
value = dataSnapshot.getValue(String.class);
Log.d("yourtag ", " Result= "value);
// ...
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
// ...
}
};
mRef.addValueEventListener(listener);
I have a problem regarding querying the firebase database using a value and getting the specific node. My schema is shown here:
In my schema 'workLocations' belongs to an 'excavationWorks', and 'excavationWorks' belongs to an 'excavationLists'.
That means that the path to a specific workLocation is excavationLists/excavationWorks/workLocations/(specific workLocation)
The problem that I have is that I want to query the workLocations node by the location value (let's say London) and get the parent node (the red circled key which is the key of the specific workLocation).
I have search and read many posts but I haven't managed to make it work.
My code looks like this:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference.child("workLocations").orderByChild("location").equalTo("London");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot workLoc : dataSnapshot.getChildren()) {
// do something with the individual "issues"
Log.d(TAG, workLoc.getKey());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Thank you
To achieve this, you need to query your database twice like this:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
DatabaseReference workLocationsRef = reference
.child("excavationLists")
.child("excavationWorks")
.child("workLocations");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
for(DataSnapshot ds : dSnapshot.getChildren()) {
String key = ds.getKey();
Query query = workLocationsRef.child(key).orderByChild("location").equalTo("London");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
String description = snapshot.child("description").getValue(String.class);
Log.d("description", description);
String partentKey = snapshot.getRef().getParent().getKey();
Log.d("partentKey", partentKey);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
query.addListenerForSingleValueEvent(eventListener);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
workLocationsRef.addListenerForSingleValueEvent(valueEventListener);
My firebase structure looks like this:
The groups use keys generated by firebase, 0 and 1 are just examples.
In those groups there is more data like "groupname".
How should I retrieve the groupnames of all groups linked to a user?
I'm on Android.
Solved by Alex.
Assuming that the groups node is a direct child of your Firebase root and inside a single group, there is a key named groupName, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference groupsRef = rootRef.child("groups");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
Log.d("TAG", name);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
};
groupsRef.addListenerForSingleValueEvent(eventListener);
If you need to be able to get only the group names of the groups that your users are linking to, you need to query twice like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userGroupsRef = rootRef.child("users").child(userKey).child("groups");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String groupKey = ds.getKey();
DatabaseReference groupKeyRef = rootRef.child("groups").child(groupKey);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("name").getValue(String.class);
Log.d("TAG", name);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
};
groupKeyRef.addListenerForSingleValueEvent(valueEventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
};
userGroupsRef.addListenerForSingleValueEvent(eventListener);
In which userKey is the key of the user from which you want the get the group ids.
Users is my root node, in that I have various childs created by getting the uid of the user who authenticated. Within these childs (uid) their are various childs like Info, General maintenance, Complaints.
I want to show some of the details like gCity, gProductModel from General maintenance child from all the users (uids). Each uid will have a different values of gCity, etc. Under General Maintenance, I want to retrieve all that data by setting it on an adapter and listview.
I am not able to retrieve it.
Database image
retreive code
When i am trying to retrieve data from the current user by using 'getuid()'(As shown below) ,its working fine . But when i try to retrieve all users data using' getkey()' , it isn't working .
user = FirebaseAuth.getInstance().getCurrentUser();
ref= FirebaseDatabase.getInstance().getReference("Users")
.child(user.getUid())
.child("General Maintenance");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(list_users.size() > 0)
list_users.clear();
for(DataSnapshot postSnapshot:dataSnapshot.getChildren())
{
Generalperson user =
postSnapshot.getValue(Generalperson.class);
list_users.add(user);
}
if(list_users.size() != 0)
{ ListViewAdapter adapter = new
ListViewAdapter(ServicehistoryActivity.this, list_users);
list_data.setAdapter(adapter);}
else
{
list_data.setVisibility(View.INVISIBLE);
k.setVisibility(View.VISIBLE);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Please use this code:
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference().child("Users");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String userId = ds.getKey();
DatabaseReference userIdRef = FirebaseDatabase.getInstance().getReference().child("Users").child(userId);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.child("General Maintenence").getChildren()) {
String gCity = ds.child("gCity").getValue(String.class);
String gEmail = ds.child("gEmail").getValue(String.class);
String gPhone = ds.child("gPhone").getValue(String.class);
//and so on
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
userIdRef.addListenerForSingleValueEvent(valueEventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
usersRef.addListenerForSingleValueEvent(eventListener);
If you get this error, Listen at /Users failed: DatabaseError: Permission denied is because you are not authorized to the Database, check the Rules Tab in the Realtime database and make this change:
{
"rules": {
".read": true,
".write":true
}
}
Hope it helps.