I am trying to retrieve the custom username the user on my app sets for themselves from my Firebase Database. I have some code in place that is functioning properly, but I do not know exactly what to set my TextView equal to in order to get the data the code is retrieving.
So here is the method that goes and gets the username from my Firebase Database.
public void getUser(final MyCallback callback) {
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.child("Users").child(uid).child("userName").getValue(User.class);
if (null!=callback) callback.onSuccess(user);
}
#Override
public void onCancelled(DatabaseError databaseError) {
//Log.d(TAG, "onCancelled: Error: " + databaseError.getMessage());
}
});
}
And then I have an interface that deals with the callback
public interface MyCallback{
void onSuccess(User user);
}
And then finally I call the getUser() void where I want the username displayed through this code.
final TextView navuserName = findViewById(R.id.navUsername);
getUser(new MyCallback() {
#Override public void onSuccess(User u) {
navuserName.setText("hello");
}
});
And where navuserName.setText("hello"); is, I want that to display the username. But I do not know what to put between the brackets in order to get the String that the getUser() void is retrieving.
This is how my database is setup
{"BP07KgV4yHa0bqpt740kuFzJQGI2" : {
"email" : "sampleEmail#gmail.com",
"userName" : "testUsername"
In your User class you need getter and setter for your field, in this case, user name.
Add them like this to the String variable that you use to store user name in your User class:
private String username;
public String getusername()
{
return this.username;
}
public void setusername(String value)
{
this.username= value;
}
// If you don't want User class to be initialized without passing a user name then you can add user name to it's constructor
public class User ( String username )
{
this.username = username;
}
To get user from Firebase you should refer to all data in this case uid node. But if you only want to get the user name then you should use it like this:
User user = new User();
String username;
username = (String) dataSnapshot.child("Users").child(uid).child("userName").getValue();
user.setusername(username);
And to retrieve the data in order to pass to the TextView use user.getusername()
Related
I am doing a project with firebase, able to save some records on the database, but retrieving it has been an issue for me, I've meddled with other posts from SO but they haven't worked for me. This is how the database looks like (An example):
And my code for retrieving the data:
private void readDataFromDB() {
databaseReference.child("users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = new User();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
user.setStrName(//Get the Name of the user);
user.setStrScore(//Get the Score of the user));
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
The User class:
public class User {
String strName, strScore;
public String getStrName() {
return strName;
}
public void setStrName(String strName) {
this.strName = strName;
}
public String getStrScore() {
return strScore;
}
public void setStrScore(String strScore) {
this.strScore = strScore;
}
}
How can I get the name and score from each specific user
In your code, you are setting values, you need to be retrieving values using the getters.
Try the following:
databaseReference.child("users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
String name = user.getStrName();
String score = user.getStrScore();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
But, first you need to add the values to the database example:
User user = new User();
user.setStrName("my_name");
user.setStrScore("20");
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("users");
ref.push().setValue(user);
Note setValue():
In addition, you can set instances of your own class into this location, provided they satisfy the following constraints:
The class must have a default constructor that takes no arguments
The class must define public getters for the properties to be assigned. Properties without a public getter will be set to their default value when an instance is deserialized
You need to add a default constructor to the POJO class public User(){} and also the field names in the class should match the ones in the database. So change this String strName, strScore; into this String name, score; and generate the getters and setters again.
Instead of creating profile in every node you can use a global profile node, and in that store the profile data with their UID, which would make it easier for you to fetch detail of single user.
-profile
-UID1
-name
-score
-UID2
-name
-score
While retrieving you can use getCurrentUser.getUid() to retrieve data for each user:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
databaseReference.child("users").child("profile").child(uid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = new User();
user = dataSnapshot.getValue(User.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
So this is my bind model class:
public class UserBanknoteAmountBindModel {
public String id;
public String userId;
public String banknoteType;
public String banknoteAmount;
public UserBanknoteAmountBindModel(){
}
public String getBanknoteAmount() {
return banknoteAmount;
}
public String getBanknoteType() {
return banknoteType;
}
public String getUserId() {
return userId;
}
public void setBanknoteAmount(String banknoteAmount) {
this.banknoteAmount = banknoteAmount;
}
public void setBanknoteType(String banknoteType) {
this.banknoteType = banknoteType;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
(idk if acess modifiers matter in this case).
I am trying to parse my data:
for (DataSnapshot banknoteAmount:dataSnapshot.getChildren()){
UserBanknoteAmountBindModel userBanknoteAmountBindModel=dataSnapshot.getValue(UserBanknoteAmountBindModel.class);
Log.wtf("hgfh", banknoteAmount.getValue().toString());
}
I see that I am receiving my data because I can log it.
{banknoteAmount=3, banknoteType=20_dollar,
userId=112371098270685247195}
Anyway my data doesn't get inside my bind model. I read somewhere that I need not only to provide getters but also setters (that's why I put those setters PS: Is the thing for the setters true?).
Any ideas?
EDIT: Database Structure https://i.stack.imgur.com/o5Hgp.png
PS: The problem was that I was using the parameter from another function for the getValue (not the foorloop variable)
To get the values of banknoteAmount, banknoteType and userId, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userBanknoteAmountRef = rootRef.child("userBanknoteAmount");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
UserBanknoteAmountBindModel userBanknoteAmountBindModel = ds.getValue(UserBanknoteAmountBindModel.class);
String banknoteAmount = userBanknoteAmountBindModel.getBanknoteAmount();
String banknoteType = userBanknoteAmountBindModel.getBanknoteType();
String userId = userBanknoteAmountBindModel.getUserId();
Log.d("TAG", banknoteAmount + " / " + banknoteType + " / " + userId);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
userBanknoteAmountRef.addListenerForSingleValueEvent(valueEventListener);
The output will be:
3 / 20_dollar / 112371098270685247195
When you are using the following line of code:
banknoteAmount.getValue().toString()
You are actually printing the String representation of banknoteAmount.getValue() which has as a return value a Map object which contains those three values.
I am using Firebase database for my project. For the last few days I tried to retrieve data from database but without luck. I tried many tutorials and questions from Stack.. Database looks like this:
Database structure
My user class
I would like to retrieve information and store it in one of the strings..
My code is:
Every time I receive value Null or an Error. I am not sure If I am using correct reference("Users").
Is there is easy way to retrieve users name and store it into the string? Thanks
First you need to have same names for the fields in your database as in your model class. Looking at you model class, there are some things that you need to do. So, I'll provide a correct way to model your class.
public class UserModelClass {
private String name, sureName, date, phoneNumber;
public UserModelClass() {}
public UserModelClass(String name, String sureName, String date, String phoneNumber) {
this.name = name;
this.sureName = sureName;
this.date = date;
this.phoneNumber = phoneNumber;
}
public String getName() {return name;}
public String getSureName() {return sureName;}
public String getDate() {return date;}
public String getPhoneNumber() {return phoneNumber;}
}
In order to make it work, you need to remove all data from the database and add fresh one. There is a workaround when storing users in a Firebase database. Instead of using that that random key provided by the push() method, to use the uid. For that, I recommend you add the data as in the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
UserModelClass umc = new UserModelClass("Jonas", "Simonaitis", "today", "123456789");
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("users").child(uid);
uidRef.setValue(umc);
To read data, please use the following code:
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
UserModelClass userModelClass = dataSnapshot.getValue(dataSnapshot.class);
String name = userModelClass.getName();
String sureName = userModelClass.getSureName();
String date = userModelClass.getDate();
String phoneNumber = userModelClass.getPhoneNumber();
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
uidRef.addListenerForSingleValueEvent(eventListener);
In one of my tutorials I have explained step by step how to use the model classes when using Firebase.
First you have to do make these declarations:
private DatabaseReference mUserDatabase;
private FirebaseUser mCurrentUser;
in onCreate you need to make smth like this:
mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
String current_uid = mCurrentUser.getUid();
mUserDatabase =FirebaseDatabase.getInstance().getReference().child("Users")
.child(current_uid);
mUserDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("uName").getValue().toString();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Now you have the user name in "name"
First change userInformationActivity class variable names to match names in the database
example : name -> uName
surname -> uSurname
then
private void showData(DataSnapshot dataSnapshot){
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
userInformationActivity user = dataSnapshot.getValue(userInformationActivity.class);
Log.d("user Name is : " + user.uName);
}
}
Aim
Save data within the Group Chat node
Current Database Tree
Within the Group Chats node, the user's messages will be sent and stored within the user's selected group chat.
As shown in the database tree, the user has sent a message saying "Hello" and his name is retrieved from the Users node
Desired Database Tree
The ---Msg ID--- is automatically generated
The ---User ID--- is retreived from the Users node
Problem
The function to allow the user to send message Only Worked Once which was the FIRST time. The following times that the app was deployed, it crashed when the user logged in.
Error - Logcat
com.google.firebase.database.DatabaseException: Failed to convert
value of type java.util.HashMap to String
ChatActivity Class - Send Chat Message function
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
jGroupChatName = getIntent().getExtras().get("groupChatName").toString();
jUserName = getIntent().getExtras().get("groupUserName").toString();
jUserNeighbourhood = getIntent().getExtras().get("groupUserHome").toString();
jChatToolbar = (Toolbar) findViewById(R.id.allUSersToolBar);
jFirebaseCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
/*UserID Start - I was trying to retrieve the current user ID and add it to the Group Chat node,
under the selected Group Chat */
assert jFirebaseCurrentUser != null;
final String currentUserID = jFirebaseCurrentUser.getUid();
jChatRoot = FirebaseDatabase.getInstance().getReference().child("Group Chats").child(jGroupChatName).child(currentUserID);
/*UserID End*/
jChatMessageText = (EditText) findViewById(R.id.chatMessageText);
jChatSendTextBtn = (ImageButton) findViewById(R.id.chatSendTextBtn);
jChatSendTextBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Map<String, Object> groupMap = new HashMap<String, Object>();
jGroupKey = jChatRoot.push().getKey();
jChatRoot.updateChildren(groupMap);
// Based on the UserID code at the top, the "currentUserID" is added as shown below
// My intentions are to have the UserID saved under the name of the Group Chat
// jGroupKey = (Name of selected Group Chat)
DatabaseReference groupMessageRoot = jChatRoot.child(jGroupKey).child(currentUserID);
Map<String, Object> groupMap2 = new HashMap<String, Object>();
groupMap2.put("name", jUserName);
groupMap2.put("msg", jChatMessageText.getText().toString());
groupMessageRoot.updateChildren(groupMap2);
}
});
}
Linked Question
Android - Firebase - Send Users to Chat Room
Future Implementations
In the future, I intend to allow the user to send pictures and video recordings by writing a code to allow the user to access their phone camera or gallery and send the pics and vids data into the Group Chats node, under the selected Group name. I would also like to retrieve data after sending, but of course, I will leave those in future questions if I am unable to solve them.
Branching of your desired database is unnecessary. You are creating an unnecessary level using UID of users. Instead, merge this layer down, i.e. combine uid, message and name. You can then use someRef.orderByKey("uid").equalTo("<user_uid>") in case you need specific user's records within that path, for example chat messages.
So, create a class called ChatMessage:
public class ChatMessage {
private String uid;
private String name;
private String message;
private Long creationTime;
public ChatMessage() {
// Default constructor required for calls to DataSnapshot.getValue(ChatMessage.class)
}
public ChatMessage(String uid, String name, String message) {
this.uid = uid;
this.name = name;
this.message = message;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public java.util.Map<String, String> getCreationTime() {
return ServerValue.TIMESTAMP;
}
#Exclude
public Long getCreationTimeLong() {
return creationTime;
}
public void setCreationTime(Long creationTime) {
this.creationTime = creationTime;
}
}
Then update your code as follows:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
chatGroupName = getIntent().getStringExtra(CHAT_GROUP_NAME);
userKey = getIntent().getStringExtra(USER_KEY);
user = getIntent().getParcelableExtra(USER);
jChatToolbar = (Toolbar) findViewById(R.id.allUSersToolBar);
jChatMessageText = (EditText) findViewById(R.id.chatMessageText);
jChatSendTextBtn = (ImageButton) findViewById(R.id.chatSendTextBtn);
jChatSendTextBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
});
}
private void sendMessage() {
String userMessage = jChatMessageText.getText().toString();
chatGroupRef = FirebaseDatabase.getInstance().getReference().child("Group Chats").child(chatGroupName);
if (!TextUtils.isEmpty(userMessage)) {
String newChatMessageKey = chatGroupRef.push().getKey();
ChatMessage newChatMessage = new ChatMessage(userKey, user.getName(), userMessage);
chatGroupRef.child(newChatMessageKey).setValue(newChatMessage);
}
}
I am looking for ways to do following:
Whenever a user registers or logs on for first time, then a record should be created in DB with the user's email-id.
Can someone please give directions, I have tried few options from my side, but none worked out correctly.
To Register User And Add Information to database
FirebaseAuth auth = FirebaseAuth.getInstance();
DataBaseRefrence ref = FirebaseData.getInstance().getReference();
auth.createUserWithEmailAndPassword(email,pass)addOnCompleteListener(context, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful())
{
FirebaseUser fUser = mAuth.getCurrentUser();
User user = new User(name,email);
ref.child("Users").child(fuser.getUid).setValue(user);
}
User class
public class User
{
public String Name;
public String Email;
// need empty constractor
public User()
{}
public User(String name,String email)
{
Name = name;
email = email;
}
public String getName()
{
return Name;
}
public String getEmail()
{
return Email;
}
To Get Value
DataBaseRefrence ref = FirebaseData.getInstance().getReference();
FirebaseUser fUser = auth.getCurrentUser();
ref.child("Users").child(fUser.getUid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if(user!=null)
{
// do what ever you want
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
To Get data from firebase you have to go from child to child
for example to get userdata myRefLinkis https://stackoverflow.com
https://stackoverflow.com/Users/UserId now get the data
so do this,
from your question i conclude that you do not have a separate form for adding new users.
in such case ,
when the user clicks on the logon button,
u can check from the database if the record exists.
for eg. query a simple sql statement
select * from users where email-id="entered value"
if it exists then open the main application
else if it doesn't exists then insert a row with the entered values and then open the application.