I'm making a game, if the player wins, then the victory is added to the database. How can I read the data from here?
and paste here:
I read the player's name in a different way, which cannot be repeated with victories and defeats.
To be able to read the data under the jjjj node, please use the following lines of code:
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference nameRef = db.child("players").child("jjjj");
nameRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
DataSnapshot snapshot = task.getResult();
String loses = snapshot.child("loses").getValue(Long.class);
String name = snapshot.child("name").getValue(String.class);
String wins = snapshot.child("wins").getValue(Long.class);
Log.d("TAG", loses + "/" + name + "/" + wins);
} else {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
}
});
The result in the logcat will be:
3/jjjj/4
Things to notice:
Always create a reference that points to the node that you want to read.
If your database is located in another lcoation than the default, check this answer out.
use this method
This is the method of fetching data from the firebase realtime database
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
reference.child("players").child(name).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Related
I need to show groups in the main activity. Here I am using the if condition but I am not getting any groups.
if (snapshot.child("Members").child(FirebaseAuth.getInstance().getUid()).exists());
Here is the whole code:
FirebaseDatabase.getInstance().getReference().child("Groups").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
list.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
if (dataSnapshot.exists()) {
if (snapshot.child("Members").child(FirebaseAuth.getInstance().getUid()).exists());
Group group = dataSnapshot.getValue(Group.class);
list.add(group);
}
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
When you attach a listener at the following reference:
FirebaseDatabase.getInstance().getReference().child("Groups")
It means that you're reading (downloading) the entire "Groups" node. Which is actually not feasible considering the fact that under that node there may be potentially multiple nodes. So if you want to check the existence of a particular element in the Realtime Database, don't do it on the client, but perform a query:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference groupsRef = db.child("Groups");
Query queryByUid = groupsRef.orderByChild("Members/" + uid);
productsRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
list.clear();
for (DataSnapshot ds : task.getResult().getChildren()) {
Group group = ds.getValue(Group.class);
list.add(group);
Log.d("TAG", group.getGroupName());
}
adapter.notifyDataSetChanged();
} else {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
}
});
In this way, you'll only download the documents that match the query and nothing more. Otherwise it will be a waste of resources and bandwidth.
Firebase Realtime Database tree
I am new to Firebase and Java. All I need to do is display the single line Key1(image linked above) to my app.
This is the java I used:
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference().child("ReNu");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
String values = dataSnapshot.getValue(String.class);
Temp.setText(values);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
The data from that specific line is not getting displayed and which means I am probably not getting the data correctly I assume.
I am not sure how to fix it- any help is highly appreciated.
If you only need to display the value of the key1 field that exists within your ReNu node, then please use the following lines of code:
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference renuRef = db.child("ReNu");
renu.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
DataSnapshot snapshot = task.getResult();
String key1 = snapshot.child("key1").getValue(String.class);
Log.d("TAG", key1);
Temp.setText(key1);
} else {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
}
});
The result in the logcat will be:
Temp=23.0*C Humidty=56.0%
Along with setting the same value to the Text TextView. Please also note that there is no need for an iteration, since there is only one child under ReNu node.
I need to retrieve specific info from Firebase Realtime Database to send push messages, but don't know how to do it, I need to get in String the device token from all the users, so tried to call Users, the should call user ids (this part is where I'm lost, don't know how to get this path), and then device token.
This is what I have :
UsersRef = FirebaseDatabase.getInstance().getReference().child("Users");
usersIDs = UsersRef.getKey().toString();
UsersRef.child(usersIDs).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NotNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
if (dataSnapshot.hasChild("device_token")) {
receiverUserDeviceToken = dataSnapshot.child("device_token").getValue().toString();
}
}
}
#Override
public void onCancelled(#NotNull DatabaseError error) {
}
});
According to your last comment:
Correct, I need to get both values.
Please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference users = rootRef.child("Users");
usersRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot userSnapshot : task.getResult().getChildren()) {
String deviceToken = userSnapshot.child("device_token").getValue(String.class);
Log.d("TAG", deviceToken);
}
} else {
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
The result in the logcat will be:
f4...XMY:APA...wr3
eff...8NT:APA...Bd7
Remember, to be able to get all the results from a DataSnapshot object, you have to iterate through the children using .getChildren().
I'm trying to read from a Firebase Database, I've read and looked everywhere, but I'm at a dead end.
Here's all that I've done.
Dependencies:
implementation 'com.google.firebase:firebase-storage:9.2.1'
implementation 'com.google.firebase:firebase-database:9.2.1'
implementation 'com.google.firebase:firebase-auth:9.2.1'
implementation 'com.google.firebase:firebase-core:9.2.1'
minSdkVersion: 15
DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference();
then in a Button onClick method, I put the listener:
mDatabase.child("List").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String savedData = dataSnapshot.getValue(String.class);
Log.d(TAG, "snapshot: " + savedData);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, "Error");
}
});
Here is a look at the Database.
Would appreciate the input.
You're trying to read a String value under List. But right under List there's no string value, rather there's a list of objects under there. To get the actual values, you'll need to navigate the JSON structure in your code.
Something like:
DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("List").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot tierSnapshot: dataSnapshot.getChildren()) {
Log.d(TAG, tierSnapshot.getKey(); // "Tier 1", "Tier 1 B"
for (DataSnapshot secondSnapshot: tierSnapshot.getChildren()) {
Log.d(TAG, secondSnapshot.getKey(); // "Tier 2", "Tier 2 B"
String str = secondSnapshot.getValue(String.class);
Log.d(TAG, str); // null, "2 B"
Long num = secondSnapshot.getValue(long.class);
Log.d(TAG, num); // 2, null
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.w(TAG, "Error", databaseError);
}
});
An extra thing to note is that your values are of a different type, with the first one being the number 2, while the second one is a string "2 B". Hence the two getValue() calls, to get the specific type out of there. You could also just do secondSnapshot.getValue() and deal with the resulting object as you'd usually do (e.g. call toString() on it).
I've traced my code to the root cause of my crashes and apparently this constructor is unable to update the variables of the class. I am getting null pointer exception when I'm trying to get data from this class. You can safely assume that the record is already in the database and all it has to do is just get the data and place it in the class/object. I simply want to get the name for now because I'm testing if the object is still null or not.
class Saver{
private String name;
// constructor of Saver class
public Saver(final String uid) {
Log.d("Saver.java","Reached here"); // this works
FirebaseDatabase.getInstance().getReference().addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(final DataSnapshot dataSnapshot) {
Log.d("Saver.java", "OnDataChange"); // does not work
if(dataSnapshot.hasChild("users/" + uid)){
LoadRecord(dataSnapshot, uid);
}
else{
// set a new record into the database
FirebaseDatabase.getInstance().getReference().child("users/" + uid).setValue(CreateNewRecord(FirebaseAuth.getInstance().getCurrentUser())).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
LoadRecord(dataSnapshot, uid);
}
else{
Log.e("Saver.java","Failed to set record in database");
}
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("LifeSaver.java","Error: " + databaseError.getMessage());
}
});
}
// This function loads the data into the object
private void LoadRecord(DataSnapshot dataSnapshot, String uid){
Log.d("LifeSaver.java","Uid:"+uid);
// load the existing record in the database
Saver temp = dataSnapshot.child("users/" + uid).getValue(Saver.class);
setName(temp.getName());
}
}
public void setName(String name) {
this.name = name;
}
private Saver CreateNewRecord(FirebaseUser firebaseUser){
Saver saver = new Saver ();
saver.setName(firebaseUser.getDisplayName());
Log.d("saver","saver name: " + saver.getName());
return continuLifeUser;
}
Obviously the function onDataChange will not run until something changed on the database.
How can I manually trigger this function, if possible?
Should I have a DataSnapshot that has the children of this node? If so, how? (show code please so I can visualize what you are explaning)
Is there a better way of doing this?
Edit 1:
Here's the logcat statements from the constructor that should have called the FirebaseDatabase:
D/Saver.java: Reached here with hA4hZrBieISwMOZaMYe7m6K5tpI3
I/DynamiteModule: Considering local module com.google.android.gms.firebase_database:4 and remote module com.google.android.gms.firebase_database:6
I/DynamiteModule: Selected remote version of com.google.android.gms.firebase_database, version >= 6
I/art: DexFile_isDexOptNeeded failed to open oat file '/data/dalvik-cache/x86_64/data#data#com.google.android.gms#app_chimera#m#00000004#DynamiteModulesC_GmsCore_prodlmp_alldpi_release.apk#classes.dex' for file location '/data/data/com.google.android.gms/app_chimera/m/00000004/DynamiteModulesC_GmsCore_prodlmp_alldpi_release.apk': Failed to open oat filename for reading: No such file or directory
D/Saver.java: Ended here
D/LoginAct.java: Name: null
For getting all the names from all users under users node, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users");
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) {}
};
usersRef.addListenerForSingleValueEvent(eventListener);
The output will be:
Michael Ong
//other names
If you want to get only the name of a particular user, please use the following code:
FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
String uid = firebaseUser.getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("users").child(uid);
ValueEventListener eventListener = 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) {}
};
uidRef.addListenerForSingleValueEvent(eventListener);
The output will be only a single record:
Michael Ong
I resolved the problem by having a loading screen. I should have remembered that the call was Async and that it needed a receiver to call the function that will place the data before moving on to the next activity.
private interface OnGetDataListener {
void onSuccess(DataSnapshot dataSnapshot);
void onFailure();
}
Here's a small code for the listener that you'll have to implement when you're calling the database to get the data. You can check for other posts similar to this one.
Hi first you should add data to database , then only it will work . Looks like there is no data available in Firebase.Just add a key value pair in firebase database , then it will be triggered.
FirebaseDatabase.getInstance().getReference().child("users/" + uid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(final DataSnapshot dataSnapshot) {
Log.d("Saver.java", "OnDataChange"); // does not work
if(dataSnapshot!=null){
LoadRecord(dataSnapshot);
}
else{
// set a new record into the database
FirebaseDatabase.getInstance().getReference().child("users/" + uid).setValue(CreateNewRecord(FirebaseAuth.getInstance().getCurrentUser())).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
LoadRecord(dataSnapshot);
}
else{
Log.e("Saver.java","Failed to set record in database");
}
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("LifeSaver.java","Error: " + databaseError.getMessage());
}
});
}
// Load record should be like this...
private void LoadRecord(DataSnapshot dataSnapshot){
Log.d("LifeSaver.java","Uid:"+uid);
// load the existing record in the database
Saver temp = dataSnapshot.getValue(Saver.class);
setName(temp.getName());
}
}