Everything is working fine, I think just userDataModel.setUserRating(aFloat / (int) dataSnapshot.getChildrenCount()); is not giving value.
And String.valueof(aFloat / (int) dataSnapshot.getChildrenCount()));
Is also giving the correct value.
FirebaseDatabase.getInstance().getReference().child("Users").child(userDataModel.getUserID()).child("Ratings")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
userDataModel1 = dataSnapshot.getValue(UserDataModel.class);
aFloat = aFloat + Float.parseFloat(Objects.requireNonNull(dataSnapshot1.getValue()).toString());
}
userDataModel.setUserRating(aFloat / (int) dataSnapshot.getChildrenCount());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
UserDataModel
public class UserDataModel {
float userRating;
public float getUserRating() {
return userRating;
}
public void setUserRating(float userRating) {
this.userRating = userRating;
}
}
Image URL: https://i.stack.imgur.com/t14Cc.png
This is happening maybe because userDataModel.setUserRating(aFloat / (int) dataSnapshot.getChildrenCount()); is returning null so you don't get a value
The problem in your code us the fact that your UserDataModel has a field named userRating, while in your database the property is actually a uid. This property is dynamic, so you cannot use a POJO class for that. If you want to get the values of those ratings, please try this:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ratingsRef = rootRef.child("Users").child(uid).child("Ratings");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
double rating = ds.getValue(Double.class);
Log.d("TAG", "rating: " + rating);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore errors!
}
};
ratingsRef.addListenerForSingleValueEvent(valueEventListener);
The output in the logcat will be values of all ratings that exist within the Ratings node.
3.5
2
Now, you can simply make the average or whatever you need with those values.
Related
How can I implement if-else to check if the value of the money field is equal or greater (pre defined value in code) checking on the Realtime database money field? Only after this verification runs the code? I did a web search but all the methods I have searched but none were successful in the implementation.
ref.child("users").child(user.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference()
.child("users").child(user.getUid()).child("money");
ref.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Object currentMoney = mutableData.getValue();
int totalMoney = 0;
if (currentMoney == null) {
totalMoney = moneyToRemove;
} else {
totalMoney = Integer.parseInt(String.valueOf(currentMoney)) - moneyToRemove;
}
mutableData.setValue(totalMoney);
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b,
DataSnapshot dataSnapshot) {
// Transaction completed
}
});
Db structure
To get all users that have the value of money property greater than or equal to 7 for example, you should definitely use a query that looks like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users");
Query moneyQuery = usersRef.orderByChild("money").startAt(7);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
ds.child("money").getRef().setValue(ServerValue.increment(money));
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
moneyQuery.addListenerForSingleValueEvent(valueEventListener);
However, if you only want to do this operation only on the logged-in user, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("users").child(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(ds.child("money").getValue(Long.class) >= 7)) {
dataSnapshot.child("money").getRef().setValue(ServerValue.increment(money));
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);
In which the money variable can be any positive number for an increment operation or a negative number for a decrement operation. Besides that, there is no need to run a transaction for a simple increment/decrement operation. We can simply use the simpler newly added ServerValue.increment(value) option. The transactions are used only when we need to read the value of the property first.
Both solutions will work, only if you change the type of your money property in the database from String to number. So please do the following change:
money: "7" //See the quotations marks?
To:
money: 7 //No quotations marks
I want to read some specific child from the parent-child, by getchild() function but this will not work properly.
FirebaseUser FUser = mAuth.getCurrentUser();
String userid = FUser.getUid();
DatabaseReference DR;
DR = FirebaseDatabase.getInstance().getReference().child("HistoryTable").child(userid);
DR.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// Iterable<DataSnapshot> root = dataSnapshot.getChildren();
// Toast.makeText(getApplicationContext(), "ds "+dataSnapshot.getChildren(),Toast.LENGTH_LONG).show();
for (DataSnapshot ds: dataSnapshot.getChildren()) {
// Toast.makeText(getApplicationContext(), "ds "+ds,Toast.LENGTH_LONG).show();
for (DataSnapshot d: ds.getChildren()) {
String Height = d.getKey() + d.getValue() + "\n".toString();
String ch = d.child("1Height:").getValue(String.class);
// tv.append(Height);
tv.append(ch);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I want to get this four child from every key.
you have to add your push id in reference :-
DR = FirebaseDatabase.getInstance().getReference().child("HistoryTable").child(userid).child("push id");
DR.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// Iterable<DataSnapshot> root = dataSnapshot.getChildren();
// Toast.makeText(getApplicationContext(), "ds "+dataSnapshot.getChildren(),Toast.LENGTH_LONG).show();
for (DataSnapshot ds: dataSnapshot.getChildren()) {
// Toast.makeText(getApplicationContext(), "ds "+ds,Toast.LENGTH_LONG).show();
for (DataSnapshot d: ds.getChildren()) {
String Height = d.getKey() + d.getValue() + "\n".toString();
String ch = d.child("1Height:").getValue(String.class);
// tv.append(Height);
tv.append(ch);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Try like this if you just want to read the value. if you want to read data only once use addListenerForSingleValueEvent()
*Try to read values by object stucture https://firebase.google.com/docs/database/android/read-and-write#basic_write
DR.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot d: ds.getChildren()) {
//below line may cause null pointer Exception
String Height = d.getKey() + d.getValue() + "\n".toString();
if(d.child("1Height:").getValue()!=null){
String ch = d.child("1Height:").getValue(String.class);
//tv.append(Height);
tv.append(ch);}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
To get the value of your 4UserId property, simply use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("HistoryTable").child(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String userId = ds.child("4UserId").getValue(String.class);
Log.d(TAG, userId);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);
The result in your logcat will be:
2Wwrjx...P2obFO83
I am looking for a way to get data from the firebase real-time database in a format like an array[] or a String.
My database looks like this:
Link to image of database
Or:
Database
|
-->Users
|
-->UID1
-->UID2
This is at the root of the database
I want to get a list of all of the UIDs in the "Users" child.
This is the code I have so far and am a bit stuck on:
DatabaseReference databaseReference = firebaseDatabase.getReference("Users");
databaseReference.addValueEventListener(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String UIDs = dataSnapshot.getValue(String.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I am a bit of a rookie as it comes to java, android studio, and firebase. I am trying to get the data in a format I know how to use like a String or an Array[] of Strings. I looked around if other people had maybe asked the same question, but I could get the answers to those questions to work/didn't understand them.
Thanks in advance for your time!
To get the a list of uids, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("Users");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> list = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String uid = ds.getKey();
list.add(uid);
}
//Do what you need to do with your list
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
usersRef.addListenerForSingleValueEvent(valueEventListener);
I recommend you to use the list only inside the callback otherwise it will be empty. If you want to use it outside the onDataChange() method, I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.
For your above question I will give both ways: ArrayList or String with delimiters
ArrayList<String> uids = new ArrayList<String>();
FirebaseDatabase.getInstance().getReference("Users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for(DataSnapshot snapshot : dataSnapshot.getChildren()) {
uids.add(snapshot.getKey());
}
}
}
#Override
public void onCancelled(DatabaseError error) {
}
});
For String
String uids = "";
FirebaseDatabase.getInstance().getReference("Users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for(DataSnapshot snapshot : dataSnapshot.getChildren()) {
uids += snapshot.getKey() + ",";
}
}
}
#Override
public void onCancelled(DatabaseError error) {
}
});
This gives an output such as: uid1,uid2,uid3,.....uidn,
You can try this:
DatabaseReference ref=
FirebaseDatabase.getInstance().getReference("Users");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
int i = 0;
for(DataSnapshot d : dataSnapshot.getChildren()) {
name[i] = d.getKey();
i++;
}
}
}//onDataChange
#Override
public void onCancelled(DatabaseError error) {
}//onCancelled
});
name[] is an array of strings!
DatabaseReference newReferance = database.getReference().child("Users");
Query query = newReferance.orderByChild("timestamp");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
chatMessages.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
HashMap<String, String> hashMap = (HashMap<String, String>) dataSnapshot1.getValue();
//String userMail = hashMap.get("useremail");
String userMessage = hashMap.get("usermessage");
String userCt = hashMap.get("usershow");
chatMessages.add(userCt + ": " + userMessage);
if (chatMessages.size() >= 10){
for (int i= 0; i < 5; i++){
//HOW ????
}
}
recyclerAdapter.notifyDataSetChanged();
}
}
Hi Dear guys. How do I select and delete the first 5 data in a real-time database? When the ArrayList reaches a certain limit, I want to delete the first 5 data from the database. I'd appreciate it if you could help with the problem.
How do I select and delete the first 5 data in a real-time database?
You can achieve this using Firebase Query's limitToFirst(int limit):
Create a query with limit and anchor it to the start of the window
And in code should look like this:
Query query = newReferance.orderByChild("timestamp").limitToFirst(5);
See I have used this limitToFirst() method that can help you find the first 5 items. To delete them, just attach a listener and inside the onDataChange() method use the following line of code:
dataSnapshot.getRef().removeValue();
final DatabaseReference newReferance = database.getReference().child("Users");
final Query query = newReferance.orderByChild("timestamp");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
chatMessages.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
HashMap<String, String> hashMap = (HashMap<String, String>) dataSnapshot1.getValue();
//String userMail = hashMap.get("useremail");
String userMessage = hashMap.get("usermessage");
String userCt = hashMap.get("usershow");
chatMessages.add(userCt + ": " + userMessage);
if (chatMessages.size() >= 10){
Query query1 = newReferance.limitToFirst(5);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
database.getReference().child("Users").setValue(null);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
recyclerAdapter.notifyDataSetChanged();
}
}
Although I'm set, it's all deleted. I can't erase the items I want. All cleared.
rootRef is the firebase database reference. whose instance we have to gained before trying to delete any value. you can see the code given below.
count = 0;
rootRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
CommonLocationClass user = postSnapshot.getValue(CommonLocationClass.class);
if (count < 5) {
rootRef.child(user.getPhNo).removeValue();
count++;
}
}
}
}
#Override
public void onCancelled (DatabaseError firebaseError){
}
});
the CommonLocationClass is a getter setter model class i have made to make the fire-base implementation easy
you can try this it works for me
public void getDataFirebase() {
/*if (chatMessages.size() == MAX_MSJ_LIMIT){
database.getReference().child("Users").removeValue();
}*/
final DatabaseReference newRefere = database.getReference().child("Users");
Query query = newRefere.orderByChild("timestamp");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
chatMessages.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
HashMap<String, String> hashMap = (HashMap<String, String>) dataSnapshot1.getValue();
//String userMail = hashMap.get("useremail");
String userMessage = hashMap.get("usermessage");
String userCt = hashMap.get("usershow");
chatMessages.add(userCt + ": " + userMessage);
recyclerAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(), databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});
if (chatMessages.size() >= 10) {
Query query1 = newRefere.orderByChild("timestamp").limitToFirst(5);
query1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
dataSnapshot.getRef().removeValue();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
It didn't just erase the first 5 data.
if (chatMessages.size() >= 10) {
Query query1 = newRefere.orderByChild("timestamp").limitToFirst(5);
query1.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()){
ds.getRef().removeValue();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I solved the problem. With this code
I have a problem, when I want get value from firebase, getValue() return null
DataSnapshot appleSnapshot and DataSnapshot dataSnapshot - in console I see Key and Value correctly in Firebase too
Database Structure
Debugging
DataSnapshot setting - return Key but don't return Value (null)
String settingKey - return correctly String Key
String settingValue - return null
Why i cant get Value from my deeper childs?
private void readData(final ValidateJoinInterface validateJoinInterface, final String name, final String password, final String user) {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot appleSnapshot : dataSnapshot.getChildren()) {
DataSnapshot setting = appleSnapshot.child(name).child("Settings").child("Password");
String settingKey = (String) appleSnapshot.child(name).child("Settings").child("Password").getKey();
String settingValue = (String) appleSnapshot.child(name).child("Settings").child("Password").getValue();
}
validateJoinInterface.validateJoin(correctName, correctPassword, correctUserId);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("DTAG", "onCancelled", databaseError.toException());
}
});
}
Assuming that the name varaible holds a String value like in your example Aa and also assuming that Aa is a direct child of your Firebase root, to solve this, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference settingsRef = rootRef.child(name).child("Settings");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("Name").getValue(String.class);
String password = dataSnapshot.child("Password").getValue(String.class);
Log.d("TAG", name + " / " + password);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
settingsRef.addListenerForSingleValueEvent(valueEventListener);
The output will be: Aa / Aaa.
You can getting any value like :
FirebaseDatabase.getInstance().getReference().child(name).child("Settings").child("Password")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messageSnapshot : dataSnapshot.getChildren()) {
Log.d(TAG,"KEY - "+messageSnapshot.getKey() + "VALUE - "+messageSnapshot.getValue());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Crashlytics.logException(databaseError.toException());
sendMessageListener.onSendMessageFailure(databaseError.getMessage());
}
});