This is my JSON Tree in the Firebase Realtime database. I just want to iterate and read through all of the items under questions. I think I am doing something silly wrong.
Under the "My App" - I have a "questions" branch and saving a bunch of data under it. Below is the tree and my code. In the code I point out the part that is crashing. Circled in red below are what I am trying to read.
public void readfromFireDB() {
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference().child("questions");
// Read from the database
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
**THIS IS THE ERROR, ques comes back as NULL**
Question ques = dataSnapshot.getValue(Question.class);
String key = dataSnapshot.getKey();
}
#Override
public void onCancelled(DatabaseError error) {
}
});
}
This Issue: ques in onDataChanged() comes back as a null reference. May be I am not accessing the children under questions properly?
By using a ValueEventListener you're accessing the list of questions, not an individual question.
To access each individual question, you'll need to loop over the snapshot:
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot questionSnapshot: dataSnapshot.getChildren()) {
Question ques = questionSnapshot.getValue(Question.class);
String key = questionSnapshot.getKey();
}
}
Related
I am storing user details 'firstname' and 'lastname' in UserNode. But when i want to retrieve that details then no data is being retrieved. I tried almost all solutions on the internet but nothing solved my problem. Here is my code for retrieving data of the current user:
FirebaseUser userr = FirebaseAuth.getInstance().getCurrentUser();
if (userr != null) {
String name = userr.getDisplayName();
Log.e("value", name);
}
but it says "println needs a message"
I also tried with this but nothing happened:
DatabaseReference DataRef;
DataRef = FirebaseDatabase.getInstance().getReference().child("UserNode");
DataRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String acctname = (String)dataSnapshot.child("firstname").getValue();
Log.e("name", acctname);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
]1
Please help me I am stuck with it
You're reading a collection of user with a ValueEventListener. As the [Firebase documentation for reading lists with a value event](Listen for value events) explains:
While using a ChildEventListener is the recommended way to read lists of data, there are situations where attaching a ValueEventListener to a list reference is useful.
Attaching a ValueEventListener to a list of data will return the entire list of data as a single DataSnapshot, which you can then loop over to access individual children.
Even when there is only a single [child node], the snapshot is still a list; it just contains a single item. To access the item, you need to loop over the result.
So in your code:
DatabaseReference DataRef;
DataRef = FirebaseDatabase.getInstance().getReference().child("UserNode");
DataRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String acctname = (String)childSnapshot.child("firstname").getValue();
Log.i("name", acctname);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Using FirebaseUser:
FirebaseUser implements UserInfo and in UserInfo's getDisplayName() documentation says
Returns the user's display name, if available.
So, it is possible that FirebaseUser.getDisplayName() return null when display name is not set. In that case Log.e() receives null as message and therefore prints println needs a message
Using your own structure:
Instead of using type conversion use getValue(Class<T>) like so:
String acctname = dataSnapshot.child("firstname").getValue(String.class);
Please, read how to retrieve data from firebase. I think you have a problem because you don't have Class Model.
Your steps:
Create model UserModel with firstname and lastname field
Use listener (example from docs):
// Attach a listener to read the data at our posts reference
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Post post = dataSnapshot.getValue(Post.class);
System.out.println(post);
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
See other answers: How to retrieve data from one single userID Firebase Android and retrieving data from firebase android
In my solution I save data from Windows form application. There is no problem. I can list them in my android app. On this point I am trying to get key value to update the data, but always I get null.
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myReference = database.getReference();
Query myTopPostsQuery = myReference.child("DURUSLAR").orderByChild("kayitid").equalTo("1298843637");
myTopPostsQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren())
{
//Childadi =postSnapshot.getKey().toString();
String anahtar=postSnapshot.getKey().toString();
Toast.makeText(getApplicationContext(),anahtar,Toast.LENGTH_LONG);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Can you please help me?
When you execute a query at a location in the Firebase Database, it will search for the property you order/filter on in each child under that location. Since you query in /DURUSLAR, Firebase looks for /DURUSLAR/{something}/kayitid. Such a property does not exist, since you only have /DURUSLAR/{something}/{pushid}/kayitid.
To fix this problem you have two options:
query at a lower level
query to the property at its (fixed) path
The first option is to create the query at a lower level in the tree:
Query myTopPostsQuery = myReference.child("DURUSLAR/K6").orderByChild("kayitid").equalTo("1298843637");
Now the query is looking for /DURUSLAR/{pushid}/kayitid and it will work.
The second option is to query for the known path of the property:
Query myTopPostsQuery = myReference.child("DURUSLAR").orderByChild("K6/-KknsAR4_KFAeZ1HVXPW/kayitid").equalTo("1298843637");
It seems unlikely you want this here, but the approach may be helpful in other situations. Often when you need this approach with push IDs in the path, you'll want to look at http://stackoverflow.com/questions/40656589/firebase-query-if-child-of-child-contains-a-value.
The reason you are getting null is because you are doing orderByChild on the wrong level of data . According to your data u need to have a child K4-> which has a unique_id_push_id -> kayitid.Therefore you need to traverse the K4 in order to get 1298843637 for key kayitid.You can follow this tutorial to understand the retrieving of data from firebase .
Query myTopPostsQuery = myReference.child("DURUSLAR").child("k6").orderByChild("kayitid").equalTo("1298843637");
myTopPostsQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren())
{
//Childadi =postSnapshot.getKey().toString();
String anahtar=postSnapshot.getKey().toString();
Toast.makeText(getApplicationContext(),anahtar,Toast.LENGTH_LONG);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Lets suppose I have this firebase JSON structure:
And I need to get all the questions which have the atribute "from" equal to "this".
I know that I can use Volley to make a StringRequest and GET all values from my questions.json. Then, in the client side I could iterate over the response and remove the ones which don't have the correct atribute, but this would only work if I have a few questions. If I have millions of questions I would need to iterate over those millions of questions.
Is there any way I could put a filter on my request to get only the question with an attribute of my choice? (Ex: search questions.json where from == this)
Try this if may be useful in your scenario
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference.child("questions").orderByChild("from").equalTo("this");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot issue : dataSnapshot.getChildren()) {
// do with your result
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You can use equalTo
Query query = reference.child("questions").orderByChild("from").equalTo("this");
I want to retrieve the messages data under a specific key. But I don't how to get the key. Please help, I'm new to firebase.
In my case right now, I want to get the key encircled below.
I have tried this code below but this returns "chat-mates" not the key.
final DatabaseReference ref =FirebaseDatabase.getInstance().getReference().child("chat").child("single-chat").child("converstation").child("chat-mates");
ref.orderByChild("receiverName").equalTo("Liza Soberano").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child: dataSnapshot.getChildren()){
String key = child.getKey();
Log.e("Key", key);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I have tried this code below but this returns "chat-mates" not the key.
You must be using DataSnapshot method to access the JSON tree.
The DataSnapshot element has a method called getKey(). That returns the key of an object.
Official Doc: DataSnapShot getKey() method
Example Code:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot objSnapshot: snapshot.getChildren()) {
Object obj = objSnapshot.getKey();
}
}
#Override
public void onCancelled(DatabaseError firebaseError) {
Log.e("Read failed", firebaseError.getMessage());
}
});
In your case, first get to the child node "conversation" and then apply the above method getKey().
You're building your path wrong and likely end up iterating a different part of the tree, one level above child-mates. In that case it would be correct that child-mates is a child key.
The problem is in the last child() call when you create the ref:
final DatabaseReference ref =FirebaseDatabase.getInstance().getReference()
.child("chat")
.child("single-chat")
.child("converstation")
.child("chat-mates");
There is no child chat-mates under converstation, so this ref won't be correct.
You probably want to do this:
final DatabaseReference ref =FirebaseDatabase.getInstance().getReference()
.child("chat")
.child("single-chat")
.child("converstation");
ref.orderByChild("chat-mates/receiverName")
.equalTo("Liza Soberano")
.addListenerForSingleValueEvent(new ValueEventListener() {
This will filter on the chat-mates/receiverName child of each chat.
Note that you're going against one of Firebase's recommendations with this data structure. Firebase recommends against nesting data types in the way you do here.
A more denormalized data model would be:
chat-mates
$chatRoomId
receiverName
senderName
chat-messages
$chatRoomId
$messageId
This way you can get the mates/participants in a chat, without accessing (or even needing to have access to) the messages themselves.
In my Android app I am using this code to retrieve posts from firebase database:
ArrayList<Post> posts = new ArrayList<>();
dbRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dsp : dataSnapshot){
String author = dsp.child("author").getValue().toString();
String text = dsp.child("author").getValue().toString();
posts.add(new Post(author,text));
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
But this returns all the posts and if there would be many of them I think it wouldn't be good idea to keep them all in memory. Is there a way to get only certain number of node's children? For example at the beginning I would like to get 10 first ones, then 10 more and so on
You're looking for limitToFirst() (or limitToLast()).
ArrayList<Post> posts = new ArrayList<>();
Query query = dbRef.orderByKey().limitToFirst(10);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dsp : dataSnapshot){
String author = dsp.child("author").getValue().toString();
String text = dsp.child("author").getValue().toString();
posts.add(new Post(author,text));
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
See the Firebase documentation on queries for an explanation of all its capabilities.
You need to use your DataSnapShot to retrieve more specific information.
There is a Firebase guide for Android that explain how to utilize: Firebase Android Guide
If you would prefer to see on Stack OverFlow a small example this answer here seems to be doing somewhat of what you would like to achieve: Firebase Get Children