How would I loop through, and get these values from the Posts node? I'm still new to Firebase... Also using Java.
I'm targeting the specific user key, by:
mPostsRef.child(userKey)
Thank you!
To get the body and title, try the following:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("Posts").child(userKey);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot datas: dataSnapshot.getChildren()){
String body=datas.child("body").getValue().toString();
String title=datas.child("title").getValue().toString();
}
}
#Override
public void onCancelled(DatabaseError error) {
}
});
The snapshot will be at direct key under the node Posts then you can loop inside the random keys and get the values of body and title.
Related
I'm trying to retrive the data of the last-child in my Firebase Database.
.
What I would like to do is to add another Records child, that is called like the last-child id-number, increased by 1.
So in this specific case, for example, I want to create a child called "3", with all its relative fields (id, months, name, time).
I've tried with the following code, but when I run it, it never enters in the addListenerForSingleValueEvent(), and I don't know why. It doesn't give me any error, but it simply doesn't enter in the method.
String name = Joe;
int months= 5;
long time = 10;
FirebaseDatabase database = FirebaseDatabase.getInstance("db-uri");
DatabaseReference myRef = database.getReference().child("Records");
myRef.limitToLast(1).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
int last_db_user = dataSnapshot.child("id").getValue(Integer.class);
int new_user = last_db_user++;
//The User class is just a class that helps setting the values in the db
User user = new User(new_user, name, months, time);
String key = String.valueOf(new_user);
myRef.child(key).setValue(user);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
I've also tried writing it like the following but, despite the fact that this time it enters in the addListenerForSingleValueEvent(), it says that it can't execute the toInteger() method because the object is null.
myRef.child("Records").limitToLast(1).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
int last_db_user = dataSnapshot.child("id").getValue(Integer.class);
int new_user = last_db_user++;
//The User class is just a class that helps setting the values in the db
User user = new User(new_user, name, months, time);
String key = String.valueOf(new_user);
myRef.child(key).setValue(user);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
Any ideas on how can I make this work?
UPDATE
String name = Joe;
int months= 5;
long time = 10;
FirebaseDatabase database = FirebaseDatabase.getInstance("db-uri");
DatabaseReference myRef = database.getReference().child("Records");
myRef.orderByChild("id").limitToLast(1).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
int last_db_user = snapshot.child("id").getValue(Integer.class);
int new_user = last_db_user++;
//The User class is just a class that helps setting the values in the db
User user = new User(new_user, name, months, time);
String key = String.valueOf(new_user);
myRef.child(key).setValue(user);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
With this code I get the following exception:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.app, PID: 28429
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
at game.GameLogic$1.onDataChange(GameLogic.java:318)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##19.2.1:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##19.2.1:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##19.2.1:55)
at android.os.Handler.handleCallback(Handler.java:900)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8393)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
It doesn't give me any error
Well, that might be because you're ignoring errors. Please always implement onCancelled, which at its minimum should be:
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
The second problem is that you're not ordering on anything, which makes it unclear what limitToLast(1) actually works on. While this may work, you should always specify an ordering. Here that seems:
myRef.orderByChild("id").limitToLast(1).addListenerForSingleValueEvent(new ValueEventListener() {
...
The next problem: when you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
You need to handle this list in your onDataChange by looping over snapshot.getChildren(). So:
myRef.limitToLast(1).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) { // 👈
int last_db_user = snapshot.child("id").getValue(Integer.class);
int new_user = last_db_user++;
//The User class is just a class that helps setting the values in the db
User user = new User(new_user, name, months, time);
String key = String.valueOf(new_user);
myRef.child(key).setValue(user);
}
}
I have been trying to retrieve data from Firebase Realtime Database, but somewhere it's going wrong.
Here is the screenshot of database
I want to retrieve all the Question(Question1,Question2,etc) data under "CS102" node and store it in arraylist.
I tried doing it in a few ways:
reference = FirebaseDatabase.getInstance().getReference().child("CreateQuizQuestions").child(code);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull #NotNull DataSnapshot snapshot) {
if(snapshot.exists()) {
for(DataSnapshot ds:snapshot.getChildren()){
String QuizName=ds.child("QuizName").getValue().toString();
String TotalQuestions=ds.child("TotalQuestions").getValue().toString();
String ques=ds.child("Question").getValue().toString();
String option1=ds.child("Option1").getValue().toString();
String option2=ds.child("Option2").getValue().toString();
String option3=ds.child("Option3").getValue().toString();
String option4=ds.child("Option4").getValue().toString();
String correctAnswer=ds.child("CorrectAnswer").getValue().toString();
GetQuestion getQuestion=new GetQuestion(ques,option1,option2,option3,option4,correctAnswer);
list.add(getQuestion);
Log.d("Data Values: ","Question:"+list.get(0).question+" Option1: "+list.get(0).option1);
Log.d("Inner Size Tag","Size of list: "+list.size());
}
} else {
Toast.makeText(getApplicationContext(),"No Data",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull #NotNull DatabaseError error) {
}
});
But somewhere it's going wrong
Please help me in finding the solution
Like this, you should be able to gather the info of all "Question1" nodes. You will have to do this for each "Question2", "Question3" node. If for example "Question2" node has different children, you won't have to use same number of variables to retrieve the data. Of course you must add another event listener because database reference will be different. If your other question children have same number of children (answer, optrion1, 2,3,4 and question) you can use the for loop I have shown you before. Hope this works for you!!!
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("CreateQuizQuestions").child("CS102").child("Question1");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull #NotNull DataSnapshot snapshot) {
if(snapshot.exists())
{
String answer=snapshot.child("Answer").getValue().toString();
String op1=snapshot.child("Option1").getValue().toString();
String op2=snapshot.child("Option2").getValue().toString();
String op3=snapshot.child("Option3").getValue().toString();
String op4=snapshot.child("Option4").getValue().toString();
String q=snapshot.child("Question").getValue().toString();
//GetQuestion getQuestion=new GetQuestion(ques,option1,option2,option3,option4,correctAnswer);
//list.add(getQuestion);
//Log.d("Data Values: ","Question:"+list.get(0).question+" Option1: "+list.get(0).option1);
//Log.d("Inner Size Tag","Size of list: "+list.size());
}
else
{
Toast.makeText(getApplicationContext(),"No data",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull #NotNull DatabaseError error) {
}
});
}
I'm trying to get value from the last node on firebase Datasebase
I've seen a few solutions but none of them worked for me.
The code is given below:
setData = FirebaseDatabase.getInstance().getReference().child("Questions");
Query lastQuery = setData.orderByKey().limitToLast(1);
lastQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("JSON_OBJ")) {
SubmitKey item = dataSnapshot.getValue(SubmitKey.class);
String key2 = item.getJSON_OBJ();
} else {
Snackbar.make(findViewById(R.id.QuestionLayout), "JSON_ObJ not found", Snackbar.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
My Constructor Class
public class SubmitKey {
private String JSON_OBJ;
public SubmitKey() {
}
public SubmitKey(String JSON_OBJ) {
this.JSON_OBJ = JSON_OBJ;
}
public String getJSON_OBJ() {
return JSON_OBJ;
}
}
instead of getting the value it is going to the else statement and showing 'JSON_OBJ not Found'.
Any help would be appreciated.
Edit: I've made some changes in the code and now it is showing no setter/field found for 0-101 found on class submitKey
D/ViewRootImpl#5b51511[Questions]: ViewPostIme pointer 0
D/ViewRootImpl#5b51511[Questions]: ViewPostIme pointer 1
And it is aslo not going inside if statement goes to else statement
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
Your onDataChange will need to take care of this list, by iterating over snapshot.getChildren():
lastQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot: snapshot.getChildren()) {
if (dataSnapshot.hasChild("JSON_OBJ")) {
SubmitKey item = dataSnapshot.getValue(SubmitKey.class);
String key2 = item.getJSON_OBJ();
} else {
Snackbar.make(findViewById(R.id.QuestionLayout), "JSON_ObJ not found", Snackbar.LENGTH_LONG).show();
}
}
}
I am making an attendance app and I need to count the particular student attendance from the Firebase. I need to count the number of "prof" occurrence and I am new to this.
DatabaseReference attendance = FirebaseDatabase.getInstance().getReference("Attendance");
attendance.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
totaldays++; // total class days
if(snapshot.child("name").getValue(String.class).equals("prof")){
//count no of days present
}
Log.e(snapshot.getKey(), snapshot.getChildrenCount() + "");
}
Log.e(TAG, totaldays + "");
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
But the result is showing null value.
In order to solve this, you need to change your database structure. You cannot query your database since your nodes are dynamically generated. As #FrankvanPuffelen mentioned in his comment, the nodes that are causing you troubles are: 04Jul2018 with dcbch... and 05Jul2018 with hello. Because Firebase can only return results that are at a fixed path under each child of the node, to solve this, I recommend you create the date as a property. This is how it can be done and this is how your database structure should look like:
Firebase-root
|
--- dcbch..._dkjh...
|
--- Prof
|
--- email: "profeamil#gmail.com"
|
--- name: "prof"
|
--- present: true
|
--- date: 1530784439 //Current timestamp
And here is the corresponding query:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.orderByChild("Prof/name").equalsTo("prof");
Now you can attach a listener and use getChildrenCount() method on the DataSnapshot object to get the number of occurrence.
If there is a prof occurrence you can add that child data in a list. In this way you can get the number of childs by using list.size() and also use this list of data in other operations if you have.
its very simple to count any field child in the root reference
for example you have a root name attendance then you count to name where type is professor
databaseReference = FirebaseDatabase.getInstance().getReference().child("Attendance").child(istrustnumberavailable);
databaseReference.limitToFirst(5);
Query query = databaseReference.orderByChild("name").equalTo("prof");
ChildEventListener removedListener = query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
if (dataSnapshot.exists()){
long count= dataSnapshot.getChildrenCount();
}
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
if (dataSnapshot.exists()){
long count= dataSnapshot.getChildrenCount();
}
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
long count= dataSnapshot.getChildrenCount();
}
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I am working on Firebase database. How can I retrieve values from database based on email entered by user in text field. Below is my database structure. Kindly help.
Here is my code:
Ref = database.getReference("Registeration");
Ref.orderByChild("UserRegistration/email").equalTo(emailval).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
user_reg user=dataSnapshot.getValue(user_reg.class);
Toast.makeText(getApplicationContext(), user.toString(), Toast.LENGTH_SHORT).show();
}
You have:
Registration
UserRegistration
12
pushid
key:values
email:emailvalue
To retrieve values always you have to go from top to bottom, so you cannot skip any node.
Only orderByChild(..) query can skip one node (which means you use this query if you want to get children that are not direct children)
Try this:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("Registration").child("UserRegistration").child("12");
ref.orderByChild("email").equalTo(emailenteredbyuser).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
String email=datas.child("email").getValue().toString();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
As you can see in the above, the reference passes through every node until node 12.
Then you use this orderByChild("email").equalTo(emailenteredbyuser) to get the email entered by the user.
for (DataSnapshot datas : dataSnapshot.getChildren()) this for loop the datas iterates in inside the direct children of 12 which is the pushid that way you do not need to retrieve the pushid to get the values inside of it.
Try this! here I am running for each loop to get each child.
Ref.child("UserRegistration").child("email").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot:dataSnapshot.getChildren()){
user_reg user=dataSnapshot.getValue(user_reg.class);
System.out.println(user.email);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});