I am creating an application that starts the home activity and creates the methods in the Firebase database. This does it correctly but each user has a variable called acoins and I want this every time someone enters if it already exists that is not set to 0 that stays with the value that has.
This is the code I have :
databaseRef.child("users/" + user.getDisplayName() + "/acoins").setValue(0);
private void setUserData(FirebaseUser user) {
nameTextView.setText(user.getDisplayName());
emailTextView.setText(user.getEmail());
idTextView.setText(user.getUid());
Glide.with(this).load(user.getPhotoUrl()).into(photoImageView);
DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference();
databaseRef.child("users/" + user.getDisplayName()).setValue(user.getEmail());
databaseRef.child("users/" + user.getDisplayName() + "/acoins").setValue(0);
}
Try this in setUserData() method
DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference dr = ref.child("users").child(user.getDisplayName).child("acoins");
dr.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Long acoins1 = (Long)dataSnapshot.getValue();
if(acoins1 != 0)
{//create toast or anything here
}
else{
databaseRef.child("users/" + user.getDisplayName() + "/acoins").setValue(0);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Related
When I read a Firebase database, the city and town variables show me to as null. Why?
Denemesiralamaisyerleri deneme = new Denemesiralamaisyerleri();
FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
String id = firebaseUser.getUid();
DatabaseReference userdata = FirebaseDatabase.getInstance().getReference().child("users").child(id);
ValueEventListener rdn = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) { // Read user info from the database
deneme = dataSnapshot.getValue(Denemesiralamaisyerleri.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(UserInterfaceBerber.this, databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
};
userdata.addValueEventListener(rdn);
city = deneme.getCity();
town = deneme.getTown();
ilin.setText(city);
ilcenin.setText(town);
Toast.makeText(UserInterfaceBerber.this, city + " " + town + " ", Toast.LENGTH_LONG).show();
My database structure like this:
users
igORGoET3gT6i8CV4wvtuN3l08z1
city:
"Antalya"
email:
"ahmetbulur#gmail.com"
namesurname:
"Ahmet bulur"
phonenum:
"05346789445"
town:
"Alanya"
Also, for this toast message, the "city" and "town" variable show as null. I expect that it shows me "Antalya" + "Alanya" for the toast message:
Toast.makeText(UserInterfaceBerber.this, city + " " + town + " ", Toast.LENGTH_LONG).show();
Because the data is loaded from Firebase asynchronous, you should use that data only when the operation completes, and this only inside the onDataChange() method, like in the following lines of code:
Denemesiralamaisyerleri deneme=new Denemesiralamaisyerleri();
FirebaseUser firebaseUser=firebaseAuth.getCurrentUser();
String id=firebaseUser.getUid();
DatabaseReference userdata=FirebaseDatabase.getInstance().getReference().child("users").child(id);
ValueEventListener rdn=new ValueEventListener() {
#Override
public void onDataChange( DataSnapshot dataSnapshot) { //read user info from database
deneme=dataSnapshot.getValue(Denemesiralamaisyerleri.class);
city=deneme.getCity();
town=deneme.getTown();
ilin.setText(city);
ilcenin.setText(town);
Toast.makeText(UserInterfaceBerber.this,city+" "+town+" ",Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(UserInterfaceBerber.this,databaseError.getMessage(),Toast.LENGTH_LONG).show();
}
};
userdata.addValueEventListener(rdn);
For more info, I recommend you see the last part of my answer 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.
I'm trying to check if the user's email is existing in my Firebase Realtime Database. I used Firebase Authenticate to get user's Google Play Email, and if the user's email is not existing on my Firebase, the user will be prompted to another activity. Here's my code:
MainActivity.class
// Let's declare Firebase
private DatabaseReference mDatabase;
private FirebaseAuth mAuth;
private FirebaseUser mUser;
#Override
public void onStart() {
super.onStart();
// Check if user is signed in (non-null) and update UI accordingly.
mDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
mUser = mAuth.getInstance().getCurrentUser();
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String dEmail = dataSnapshot.getValue().toString();
String gEmail = mUser.getEmail();
for(DataSnapshot data: dataSnapshot.getChildren()){
if(data.child("email").child(EncodeString(gEmail)).exists()) {
Toast.makeText(getApplicationContext(), "There's one: " + EncodeString(gEmail), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "No email: " + EncodeString(gEmail), Toast.LENGTH_LONG).show();
}
}
/*
if(dEmail == gEmail) {
startActivity(new Intent(getApplicationContext(), RegisterActivity.class));
finish();
} else {
Toast.makeText(getApplicationContext(), "No email", Toast.LENGTH_LONG).show();
}*/
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
public static String EncodeString(String string) {
return string.replace(".", ",");
}
public static String DecodeString(String string) {
return string.replace(",", ".");
}
Here's the structure of my Firebase Realtime Database
UPDATE: The question is how can I check if the email (the email is the one in my google play which is sholomon12#g..) is exisiting in my database. Note: I got the same email inserted, I just replaced the one in database with comma since I can't insert dot in firebase database
There is a workaround here when creating users in a Firebase database. Instead of using that random generated id provided by the push() method, use the email address. Your database structure should look like this:
Firebase-root
|
--- users
|
--- john#email,com
|
--- //user details
Now to check the users for existens, you can use exists() method on DatabaseReference object. So to chieve this, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference yourRef = rootRef.child("users").child("john#email,com");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
//do something
} else {
//do something else
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
yourRef.addListenerForSingleValueEvent(eventListener);
So, this is how my Firebase database looks like:
I am currently trying to read the value of UserInformation/Shift/zTZ0U1K8aGb6bP94YTUA50ZwIlx2/Shift in order to set the value of ShiftInformation/1514855312873/Team/zTZ0U1K8aGb6bP94YTUA50ZwIlx2 to null.
When I press a button "buttonMyShift", I need to read the value "1514855312873" because it was generated from System.getCurrentTimeMillis().
I have been trying to accomplish that by changing the value inside a "onDataChange" method, ut the app either crashes or deletes only UserInformation/Shift.
Here is my activity code:
if (view == buttonMyShift){
final FirebaseUser user = mAuth.getCurrentUser();
final FirebaseDatabase database = FirebaseDatabase.getInstance();
databaseReference = database.getReference("UserInformation/Shift/").child(user.getUid()).child("Shift");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
//Read the value of UserInformation/Shift/user.getUid()/Shift
SHIFT uShift = dataSnapshot.getValue(SHIFT.class);
//Setting the value of userShift to UserInformation/Shift/user.getUid()/Shift
String userShift = uShift.toString().trim();
//Setting the value of ShiftInformation/userShift/Team/user.getUid() to null
mReference = database.getReference("ShiftInformation").child(userShift).child("Team").child(user.getUid());
mReference.setValue(null);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
//set UserInformation/Shift/user.getUid to null
SHIFT nshift = new SHIFT(null);
databaseReference.setValue(nshift);
Toast.makeText(MainMenuActivity.this,"Adeus!",Toast.LENGTH_SHORT).show();
//leave the activity
Intent intent = new Intent(MainMenuActivity.this,BadgeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(intent);
}
Thanks For The Help!
To get the value of your Shift field, which is 1514855312873, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference shiftRef = rootRef.child("UserInformation").child("Shift").child(user.getUid()).child("Shift");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String shift = dataSnapshot.getValue(String.class);
Log.d("TAG", shift);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
shiftRef.addListenerForSingleValueEvent(eventListener);
The output will be:
1514855312873
Your DatabaseReference was correct but the problem in your code is that you are using getChildren() method when there is no need.
Hey I am trying to sort my data in ascending order but the data is getting displayed in the order of how they are stored in the database:
This is the function being used to sort the data to find the least time.
private void getTimeTaken1(final String name) {
final DatabaseReference databaseReference1 = FirebaseDatabase.getInstance().getReference().child("users");
final Query query = databaseReference1.orderByChild("timeTaken").limitToLast(10);
Log.e(TAG, "getTimeTaken1: " + name);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int rank = 1;
for (DataSnapshot userAnswerSnapshot : dataSnapshot.getChildren()) {
if (yourTimeArraylist.size() < 10) {
if (userAnswerSnapshot.child("questions").child(name).hasChild("timeTaken")
&& userAnswerSnapshot.child("questions").child(name).child("checkAnswerCorrect").getValue(String.class).equals("1")) {
Log.e("", "User " + " " + userAnswerSnapshot.child("questions").child(name).child("timeTaken").getValue().toString());
yourTimeArraylist.add(new PreviousDayRank(userAnswerSnapshot.child("random").getValue(String.class),
userAnswerSnapshot.child("name").getValue(String.class),
timetaken(userAnswerSnapshot.child("questions").child(name).child("timeTaken").getValue(Integer.class)),
rank));
Log.e("", "onDataChange: user" + userAnswerSnapshot.child("questions").child(name).child("timeTaken").getValue());
rank++;
} else {
yourTimeArraylist.add(new PreviousDayRank(userAnswerSnapshot.child("random").getValue(String.class), userAnswerSnapshot.child("name").getValue(String.class), "-", rankl̥));
rank++;
}
}
}
query.removeEventListener(this);
databaseReference1.removeEventListener(this);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Your DatabaseReference is wrong. Please use this code:
final DatabaseReference databaseReference1 = FirebaseDatabase.getInstance().getReference().child("users").child(userId).child("questions").child(questionNumber);
final Query query = databaseReference1.orderByChild("timeTaken").limitToLast(10);
Where userId and questionNumber are the id's generated by push() method and the second by you.
Hope it helps.
At this line of my code in my OnDataChange() method in the ValueEvenListener:
int latest = dataSnapshot.getValue(Integer.class);
I'm getting a DatabaseException with the error Failed to convert a value of type java.util.HashMap to int.
However, in my database, you can take a look at the image below:
It is obviously not a HashMap but an int. Is this a bug or am I doing something wrong? What can I do to fix it? Why is it retrieving a Hashmap when the value is int?
Full dataSnapshot:
final DatabaseReference database = FirebaseDatabase.getInstance().getReference();
database.child("Campaigns").child(key).child("count");
database.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int latest = dataSnapshot.getValue(Integer.class);
button.setText(latest + "");
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(context, context.getString(R.string.error) + ": " + databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
Database:
Campaigns:{
-JDKKDJIIDJFIDJKDK:{
count:2432
}
}
It turns out I had to child dataSnapshot to my destination again. E.g:
int latest = dataSnapshot.child("Campaigns").child(key).child("count").getValue(Integer.class);
By default dataSnapshot is actually my whole database.
Your ValueEventListener is attached to the whole database.
// This line gets a reference to the whole database
final DatabaseReference database = FirebaseDatabase.getInstance().getReference();
// This line creates a child DatabaseReference, but you don't assign
// the child to a variable
database.child("Campaigns").child(key).child("count");
// This line adds a ValueEventListener to the whole database
database.addValueEventListener(new ValueEventListener() {
What you want instead is this:
final DatabaseReference database = FirebaseDatabase.getInstance().getReference()
final DatabaseReference countRef = database.child("Campaigns").child(key).child("count")
countRef.addValueEventListener(new ValueEventListener() {
// ...
});
You can see that in the latter example the ValueEventListener is attached to the child reference, not to the root.
This should work if we assume that the dataSnapshot is right.
final DatabaseReference database = FirebaseDatabase.getInstance().getReference();
database = database.child("Campaigns").child(key).child("count"); // replaced
database.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int latest = Integer.valueOf(dataSnapshot.getValue().toString()); // replaced
button.setText(latest + "");
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(context, context.getString(R.string.error) + ": " + databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
Reminder : addValueEventListener will run everytime there is a change in the dataSnapshot.
If you want to run it just once use addListenerForSingleValueEvent instead.
HashMap<String, String> hashMap = (HashMap<String, String>) dataSnapshot1.getValue();
System.out.println("hehe " + hashMap);
String demo = String.valueOf(hashMap.get("sets"));
String name = String.valueOf(hashMap.get("name"));
The COde Above ^^^ Worked fine for me.