I would like to list the users who registered to the system.
MainPage:
List<User> users;
databaseReference = FirebaseDatabase.getInstance().getReference("Users");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists())
{
for(DataSnapshot postSnapShot:dataSnapshot.getChildren())
{
User user = postSnapShot.getValue(User.class);
users.add(user);
customAdapter.notifyDataSetChanged();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("selam", "onCancelled: " + databaseError );
}
});
User Java Class
public class User {
private String email ="";
private String nickname="";
private String status="";
private String uid="";
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
İmages
You get that NullPointerException because you haven't initialized your users list. To solve this, please use the following code:
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists())
{
List<User> users = new ArrayList<>(); //Initialize the list
for(DataSnapshot postSnapShot : dataSnapshot.getChildren())
{
User user = postSnapShot.child("userInfo").getValue(User.class);
users.add(user);
}
customAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("selam", "onCancelled: " + databaseError );
}
});
Please also note, that I moved customAdapter.notifyDataSetChanged();, outside the for loop and I have also added .child("userInfo") call because there is an extra level in your database tree.
Related
In my Android app, I have a database repository to contact Firebase Realtime Database and a service layer with some methods. My SaveUserProfile method works but I keep getting a null pointer on my GetUserFromUid.
The 'user' object it returns is null and I don't know why. The node in my DB is called "users" (all lowercase) and I want to retrieve a user as a model via their userId and display the name and email onscreen.
Can anybody see where I'm going wrong?
My DbContext:
public class DbContext implements IDbContext {
User user = null;
Context context;
DatabaseReference databaseUsers = FirebaseDatabase.getInstance().getReference("users");
public DbContext(Context context){
super();
this.context = context;
}
#Override
public void AddUserAccount(User user1) {
databaseUsers.child(user1.userId).setValue(user1);
}
#Override
public User GetUserFromFirebase(String uid) {
databaseUsers.child(uid)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
user = dataSnapshot.getValue(User.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
return user;
}
My DbService:
public class DbService implements IDbService {
//instance of DbContext for firebase handling
private DbContext dbContext;
public DbService(Context context){
super();
dbContext = new DbContext(context);
}
#Override
public User SaveUserProfile(User u) {
dbContext.AddUserAccount(u);
return u;
}
#Override
public User GetUserFromUid(String uid) {
User user = dbContext.GetUserFromFirebase(uid);
return user;
}
My User model:
public class User {
public String userId;
public String name;
public String email;
public String account;
//constructor required for calls to DataSnapshot.getValue(User.class)
public User(){
}
public User(String userId, String name, String email, String account) {
this.userId = userId;
this.name = name;
this.email = email;
this.account = account;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
My activity where I want to display the users' details:
public class DetailsActivity extends AppCompatActivity {
//tag
private static final String TAG = DetailsActivity.class.getSimpleName();
//firebase auth
private FirebaseAuth mAuth;
//variables
private TextView inputName, inputEmail;
private DatabaseReference mFirebaseDatabase;
private String userId;
public String currentUserAccount;
public String teacherAccountNav = "Teacher";
public User userDetails;
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
inputName = findViewById(R.id.nameTextView);
inputEmail = findViewById(R.id.emailTextView);
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
assert user != null;
userId = user.getUid();
getUserDetails(userId);
inputName.setText(userDetails.name);
inputEmail.setText(userDetails.email);
}
public User getUserDetails(String uid){
DbService dbService = new DbService(this);
userDetails = dbService.GetUserFromUid(uid);
return userDetails;
}
EDITS BELOW
My callback:
public interface Callback {
void myResponseCallback(User user);
}
My EDITED DbContext:
public class DbContext implements IDbContext {
User user = null;
Context context;
DatabaseReference databaseUsers = FirebaseDatabase.getInstance().getReference("users");
public DbContext(Context context) {
this.context = context;
}
#Override
public void AddUserAccount(User user1) {
databaseUsers.child(user1.userId).setValue(user1);
}
#Override
public void GetUserFromFirebase(String uid, final Callback callback) {
databaseUsers.child(uid)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
user = dataSnapshot.getValue(User.class);
callback.myResponseCallback(user);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
My EDITED DbService:
public class DbService implements IDbService {
//instance of DbContext for firebase handling
public DbContext dbContext;
public DbService(Context context){
super();
dbContext = new DbContext(context);
}
#Override
public User SaveUserProfile(User u) {
dbContext.AddUserAccount(u);
return u;
}
#Override
public User GetUserFromUid(String uid) {
final User[] user1 = {new User()};
dbContext.GetUserFromFirebase(uid, new Callback() {
#Override
public void myResponseCallback(User user) {
user1[0] = user;
}
});
return user1[0];
}
My EDITED Activity:
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
inputName = findViewById(R.id.nameTextView);
inputEmail = findViewById(R.id.emailTextView);
FirebaseDatabase mFirebaseInstance = FirebaseDatabase.getInstance();
//reference to 'users' node
mFirebaseDatabase = mFirebaseInstance.getReference("users");
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
assert user != null;
userId = user.getUid();
getUserFromFirebase(userId);
}
public void getUserFromFirebase(String uid){
userDetails = (new DbService(this)).GetUserFromUid(uid);
inputEmail.setText(userDetails.email);
inputName.setText(userDetails.name);
}
Debug BEFORE edits:
Debug AFTER edits:
As you can see from the debug, before the callback interface, userDetails was null. After the interface implementation, userDetails is not null but all of the object values are null. I don't know why this is as they are filled in the database. Any ideas?
I want to read data from Firebase but Log.d("Uservalue", ""+value); return null for me, what should I do?
MainActivity.java:
FirebaseUser user = mAuth.getCurrentUser();
DatabaseReference myRef = FirebaseDatabase.getInstance().getReference("USERS").child(user.getUid());
User user1 = new User(user.getEmail(), user.getDisplayName(), user.getUid(), user.getPhotoUrl().toString());
/* write to firebase database */
myRef.setValue(user1);
/*read*/
myRef.child(user.getUid()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User value = dataSnapshot.getValue(User.class);
Toast.makeText(MainActivity.this, "User", Toast.LENGTH_SHORT).show();
Log.d("Uservalue", ""+value);
}
#Override
public void onCancelled(DatabaseError databaseError) { }
});
User.java:
public class User{
private String email;
private String id;
private String imgurl;
private String name;
public User(){
// Default constructor required for calls to DataSnapshot.getValue(User.class)
}
public User(String email, String name, String id, String imgurl) {
this.email = email;
this.id = id;
this.imgurl = imgurl;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getname() {
return this.name;
}
public void setname(String username) {
this.name = username;
}
public String getImgurl() {
return imgurl;
}
public void setImgurl(String imgurl) {
this.imgurl = imgurl;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
And my firebase data:
And Logcat return null
020-06-03 17:53:12.810 8720-8720/com.example.chatapp D/Uservalue: null
Can anyone help me? Thank you.
And then
I want to ask a question, why User value = dataSnapshot.getValue(User.class); know the name in firebase = name in User, the email in firebase = email in User ......, so that I use value.getName() can get my name's data.
The following call to setValue():
myRef.setValue(user1);
It's an asynchronous operation. So if you want to use (read) that data, you should wait until the write operation is completed. So please check the following lines of code:
uidRef.setValue(user1).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
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) {
User user = dataSnapshot.getValue(User.class);
Log.d("TAG", user.getName());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore errors!
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);
}
}
});
Your myRef is already on USERS/$uid node. So change your ValueEventListener to
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
User value =
dataSnapshot.getValue(User.class);
Toast.makeText(MainActivity.this, "User",
Toast.LENGTH_SHORT).show();
Log.d("Uservalue", ""+value);
}
#Override
public void onCancelled(DatabaseError databaseError) { }
});
Edit: Or change your Database Reference to
myRef=FirebaseDatabase().getInstance(). getReference("USERS");
myRef.child(user.getUid).setValue(your data);
myRef.child(user.getUid).addValueEventListener(//the rest are same
);
Your myRef is already pointing to your user node
DatabaseReference myRef = FirebaseDatabase.getInstance().getReference("USERS").child(user.getUid());
You are trying listen to another branch of your user node by mentioning uid
myRef.child(user.getUid()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User value = dataSnapshot.getValue(User.class);
Toast.makeText(MainActivity.this, "User", Toast.LENGTH_SHORT).show();
Log.d("Uservalue", ""+value);
}
#Override
public void onCancelled(DatabaseError databaseError) { }
});
Change this code to this
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User value = dataSnapshot.getValue(User.class);
Toast.makeText(MainActivity.this, "User", Toast.LENGTH_SHORT).show();
Log.d("Uservalue", ""+value);
}
#Override
public void onCancelled(DatabaseError databaseError) { }
});
First time working with Firebase realtime database I'm trying to read data from the database with Android application this is my first experience I'm sorry I'm used to working with MySQL so this JSON format seem to be complicated for me
I get the error No setter/field for found on class.
private FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference mDbRef = mDatabase.getReference().child("users");
mDbRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Users user = dataSnapshot.getValue(Users.class);
Log.d("result", "User name: " + user.getName() + ", email " + user.getEmail());
}
#Override
public void onCancelled(DatabaseError error) {
Log.w("error", "Failed to read value.", error.toException());
}
});
database example
and this my Users class
public class Users {
private String phone;
private String email;
private String name;
private String adresse;
private String ville;
private String zip;
public Users() {
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAdresse() {
return adresse;
}
public void setAdresse(String adresse) {
this.adresse = adresse;
}
public String getVille() {
return ville;
}
public void setVille(String ville) {
this.ville = ville;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
}
I have attached an image for the struct of the database if anyone have any solution please help me
To solve this problem, you need to loop through entire users node using getChildren() method, like in the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Users users = ds.getValue(Users.class);
Log.d("result", "User name: " + user.getName() + ", email " + user.getEmail());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
usersRef.addListenerForSingleValueEvent(valueEventListener);
The result in your logcat will be the name and email of all users.
You should use ChildEventListener as your data is a list , if u use ValueEventListener then it will return the entire list of data as a single DataSnapshot which is not the recommended way.
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users");
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Users user = dataSnapshot.getValue(Users.class);
Log.d("result", "User name: " + user.getName() + ", email " + user.getEmail());
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
usersRef.addChildEventListener(childEventListener);
JSON Image Link
i want to get all the images from my firebase database with this code
FirebaseDatabase mFirebaseInstance = FirebaseDatabase.getInstance();
mFirebaseInstance.getReference("actors").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
To solve this, you need to loop through the DataSnapshot object using getChildren() method. So please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("actors").orderByChild("image");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String image = ds.child("image").getValue(String.class);
Log.d(TAG, image);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
query.addListenerForSingleValueEvent(valueEventListener);
The output in your logcat, will be all the image urls.
You can better use addListenerForSingleValueEvent instead of addValueEventListener as it will be called once so it will be very helpful, please try below code
ArrayList<String> arr_imageList = new ArrayList<>();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
reference.child("actors").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
arr_imageList.clear();
if (dataSnapshot.exists()) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
ActorsModel actorsModel = dataSnapshot1.getValue(ActorsModel.class);
if (actorsModel != null && actorsModel.getImage() != null) {
arr_imageList.add(actorsModel.getImage());
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
and please add model class for ActorsModel which is below
public class ActorsModel implements Serializable {
private String children;
private String country;
private String description;
private String dob;
private String height;
private String image;
private String name;
private String spouse;
public ActorsModel() {
}
public ActorsModel(String children, String country, String description, String dob, String height, String image, String name, String spouse) {
this.children = children;
this.country = country;
this.description = description;
this.dob = dob;
this.height = height;
this.image = image;
this.name = name;
this.spouse = spouse;
}
public String getChildren() {
return children;
}
public void setChildren(String children) {
this.children = children;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSpouse() {
return spouse;
}
public void setSpouse(String spouse) {
this.spouse = spouse;
}
}
I have a Firebase databse structure like this :
the firebase database structure
Now I want to access the items in the node "comingSoonPages" to a model class. How can i get the reference to these different user specified items in that node?
The database reference :
mUpcomingDatabaseReference = mFirebaseDatabase.getReference().child("comingSoonPages").child("blrKoramangala")
now the listener to the reference is as :
mValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapShot : dataSnapshot.getChildren()){
Log.e("snap" , String.valueOf(snapShot));
try{
UpcomingProperty property = snapShot.getValue(UpcomingProperty.class);
Log.e("name" , String.valueOf(property.getName()));
}catch (Exception ex){
ex.printStackTrace();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
mUpcomingDatabaseReference.addValueEventListener(mValueEventListener);
when i try to log the names in each of the nodes , i get NPE and the value is null.
The model class in which i am mapping is :
public class UpcomingProperty implements Serializable {
//private Amenities amenities;
private List<String> amenities;
private Coordinates coordinates;
private Image image;
private String link;
private String location;
private String name;
private Text text;
private List<String> sortParameter;
private EarlyBird earlyBird;
public UpcomingProperty(){}
public List<String> getAmenities() {
return amenities;
}
public void setAmenities(List<String> amenities) {
this.amenities = amenities;
}
public Coordinates getCoordinates() {
return coordinates;
}
public void setCoordinates(Coordinates coordinates) {
this.coordinates = coordinates;
}
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Text getText() {
return text;
}
public void setText(Text text) {
this.text = text;
}
public List<String> getSortParameter() {
return sortParameter;
}
public void setSortParameter(List<String> sortParameter) {
this.sortParameter = sortParameter;
}
public EarlyBird getEarlyBird() {
return earlyBird;
}
public void setEarlyBird(EarlyBird earlyBird) {
this.earlyBird = earlyBird;
}
}
Thanks.
the extended firebase node :
extended node values
To get that data, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference comingSoonPagesRef = rootRef.child("comingSoonPages");
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) {}
};
comingSoonPagesRef.addListenerForSingleValueEvent(eventListener);
The out will be the only the names. But you can get also all the other values in the same way.
If you want to use the model class, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference comingSoonPagesRef = rootRef.child("comingSoonPages");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
UpcomingProperty upcomingProperty = ds.getValue(UpcomingProperty.class);
Log.d("TAG", upcomingProperty.getName());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
comingSoonPagesRef.addListenerForSingleValueEvent(eventListener);
You'll have the same output.
Assuming that comingSoonPages holds a list of item, You need to add a ChildEventListener on the comingSoonPages reference if you want to access all the child nodes of that.
DatabaseReference upcomingItemsRef = mFirebaseDatabase.getReference().child("comingSoonPages");
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
if(dataSnapshot.exists()) {
// Handle each individual node like blrKoramangala, cyberHub here.
String key = dataSnapshot.getKey();
// Get the UpcomingProperty object here.
UpcomingProperty property = dataSnapshot.getValue(UpcomingProperty.class);
Log.d(TAG, "property.getName():" + property.getName();
}
}
// Other methods of ChildEventListener go here
};
upcomingItemsRef.addChildEventListener(childEventListener);
You can read more about working with lists of data here.
However, if that's not a list, here's what you're doing wrong:
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Don't do this. It will get the children of blrKoramangala and
// those won't be of UpcomingProperty type.
// Remove and replace with dataSnapshot.exists()
for (DataSnapshot snapShot : dataSnapshot.getChildren()){
...
}
}