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.
Related
I create 2 android apps, for the user and for admin. The user app can crud the "pelanggaran", the admin app can see all the pelanggaran realtime.
Here, I am stuck in retrieving the data in real time for the admin app. Here's the database hierarchy.
this is the references: pelanggaran and user
each user has pelanggaran. so, the first child of pelanggaran is userID, then the pelanggaranID, then the values
I tried googling, I got it, but it is not real-time. Here's my code
private void refreshList(){
databaseUser = FirebaseDatabase.getInstance().getReference("User");
pelanggaranList = new ArrayList<>();
databaseUser.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
pelanggaranList.clear();
long numberUsers = dataSnapshot.getChildrenCount();
Log.w("total user", "" + numberUsers);
for (DataSnapshot dsUser : dataSnapshot.getChildren()){
User user = dsUser.getValue(User.class);
final String userId = user.getUserId();
Log.w("id user", userId);
databasePelanggaran = FirebaseDatabase.getInstance().getReference("Pelanggaran").child(userId);
databasePelanggaran.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot1) {
for (DataSnapshot dsPelanggaran : dataSnapshot1.getChildren()){
Pelanggaran pelanggaran = dsPelanggaran.getValue(Pelanggaran.class);
Log.w("id pelanggaran", userId + " : " + pelanggaran.getIdPelanggaran());
pelanggaranList.add(pelanggaran);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
PelanggaranAdapter pelanggaranAdapter = new PelanggaranAdapter(MainActivity.this, pelanggaranList);
recyclerView.setAdapter(pelanggaranAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
It can take all the values from each user but it is not real time. And sometimes the data doesn't appears. What should I do to make it realtime?
Answer needed urgently. I'm trying to retrieve a single value school name as marked in the snapshot attached below and populate it to my android spinner from my firebase-database
private class FireBaseConnection{
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference rootRef = database.getReference().child("root");
DatabaseReference reg_schools = rootRef.child("reg_schools");
}
private ArrayList<String> retrieveAllSchools(){
pBar.setMessage("Please Wait..Retrieving Schools...");
pBar.show();
FireBaseConnection fireBaseConnection = new FireBaseConnection();
String key = fireBaseConnection.reg_schools.push().getKey();
fireBaseConnection.reg_schools.child(key).child("school_name").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
resultProcessorObject = snapshot.getValue(SchoolObject.class);
schools_retrieved = resultProcessorObject.getSchool_name();
schools.add( schools_retrieved);
//schools = (ArrayList<Object>) snapshot.getValue();
// Toast.makeText(Main2Activity.this, "Schools are : " + schools, Toast.LENGTH_SHORT).show();
}
Toast.makeText(Main2Activity.this, "Schools are : " + schools, Toast.LENGTH_SHORT).show();
pBar.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return schools;
}
So I want to answer my question..I made it work with the help of #Alex Mamo video
so everything remained unchanged..all i did was tweak my code a bit
Instead of
fireBaseConnection.reg_schools.child(key).child("school_name").addValueEventListener(){
//Then my codes here
}
Instead i did
fireBaseConnection.reg_schools.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
resultProcessorObject = snapshot.child("school_name").getValue(String.class);
//schools_retreived = resultProcessorObject.getSchool_name();
schools.add(resultProcessorObject);
count = dataSnapshot.getChildrenCount();
Toast.makeText(Main2Activity.this, "Total number of " + count + " schools were retreived ", Toast.LENGTH_SHORT).show();
// schools = (ArrayList<Object>) snapshot.getValue();
// Toast.makeText(Main2Activity.this, "Schools are : " + schools, Toast.LENGTH_SHORT).show();
}
Toast.makeText(Main2Activity.this, "Schools are : " + schools, Toast.LENGTH_SHORT).show();
pBar.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
So Basically i used the snapshot to reference the node "school_name" i'm looking for in the onDataChange Method
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) {
}
});
How to only retrieve email addresses inside the key, not all the items. I have an items Name and Email, but I only want to retrieve EMAIL.
example:
Email: HOTMAIL
Email: GMAIL
first make database reference as
mReference= FirebaseDatabase.getInstance().getReferenceFromUrl(FIREBASE_URL_USERS);
here FREBASE_URL_USERS is a url of users key you can get it from firebase console.
it is a combination of your unique_fiirebase_root_url / User01
then get snapshot of data as
mDatabseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dataSnapshot.getValue("Email");
// use log to check whetehr you are getting email or not
#Override
public void onCancelled(DatabaseError databaseError) {
// log error and do something
}
});
Assuming that the user emails are unique, you can query the users records by its email value as follows:
final String email = "hani.mehdi#email.com";
ValueEventListener onFindListener = new ValueEventListener() {
#Override
public void onCancelled(DatabaseError error) {
Log.e(TAG, error.getMessage());
}
#Override
public void onDataChange(DataSnapshot snapshot) {
Map<String, User> result = snapshot.getValue(Map.class);
if (result.contains(email) {
User user = result.get(email);
Log.i(TAG, user.toString());
} else {
Log.d(TAG, "Not found: " + email);
}
}
};
DatabaseReference userReference = database.getReference("users")
.orderByChild("email")
.equalTo(email)
.addListenerForSingleValueEvent(onFindListener);
I am having problem in retrieving data from firebase. I have one root user's node and then inside that root I have one userID child node. Inside that child node I am storing user information according to its blood group.
Now, what I want is to fetch the name and email according to blood group, say fetch all user data whose blood group is B+.
Also, please tell me on how to fetch all entries in the firebase and show on textView.
//show data on text view
datashow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("inside click", "onClick: ");
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference db = database.getReference();
db.child("users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if (user == null) {
Log.e(TAG, "User data is null!");
return;
}
Iterable<DataSnapshot > children = dataSnapshot.getChildren();
Log.i("children", "onDataChange: " + children);
for(DataSnapshot child : children)
{
Map<String , String> map = (Map)child.getValue();
Log.i("inside", "onDataChange: " + map);
name = map.get("name");
email = map.get("email");
dateof = map.get("userDob");
showData(name , email , dateof );
Log.i("datasnap", "onDataChange: data snapshot " + name + email + dateof);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
this is my snapshot for Firebase database
enter image description here
db.child("users").orderByChild("userBloodGroup").equalTo("B+").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
List<User> data = new ArrayList<>();
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot :
dataSnapshot.getChildren()) {
User element = snapshot.getValue(User.class);
element.setKey(snapshot.getKey());
data.add(element);
}
for (User user: data){
Log.i(TAG,"user name: " +user.getName());
Log.i(TAG,"user email: " +user.getEmail());
Log.i(TAG,"user dob: " +user.getUserDob());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.i(TAG, "loadPost:onCancelled", databaseError.toException());
}
});
To query for all users with the bloodGroup B+, use a Firebase Query:
firebaseReference("users").orderByChild("userBloodGroup").equalTo("B+")
To get all the data of the users, you could use a Listener to get all of them and put them in whatever TextView you need. You could check the documentation on Firebase on how they read data. https://firebase.google.com/docs/database/android/read-and-write