I want to get user's name from my firebase database but I'm getting this error
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
here is my firebase database structure:
below is my code which is proffering the same error:
public class MyAccount extends AppCompatActivity {
private Button mSetupButton;
private EditText mSetupName;
private EditText mSetupBio;
private ImageButton mSetupImageButton;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private String mPostKey=null;
private DatabaseReference mDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_account);
mAuth=FirebaseAuth.getInstance();
String user_id=mAuth.getCurrentUser().getUid();
mDatabase= FirebaseDatabase.getInstance().getReference().child("Profiles");
mPostKey=getIntent().getExtras().getString(user_id);
mSetupName = (EditText) findViewById(R.id.accountName);
mSetupBio = (EditText) findViewById(R.id.accountBio);
mSetupButton = (Button) findViewById(R.id.accountButton);
mSetupImageButton = (ImageButton) findViewById(R.id.accountImageButton);
mDatabase.child(mPostKey).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String post_name = (String) dataSnapshot.child("Name").getValue();
mSetupName.setText(post_name);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
Apparently the error is in getting user id.
just update or add as per your naming convention and your requirements in FirstScreen(i have almost done the required changes you need to make).
Intent i = new Intent(FirstScreen.this, MyAccount.class);
String user_id;
i.putExtra("user_id", user_id);
Assuming the previous activity is MainActivity, then this is the code for it to put the extra to the intent
String mPostKey = // the post key value here
Intent intent = new Intent(MainActivity.this, MyAccount.class);
intent.putExtra("post_key", mPostKey);
startActivity(intent);
To get the extra in MyAccount activity, call
mPostKey = getIntent().getExtras().getString("post_key");
By the way, I recommend you to change your database structure by putting the uid as the "post key", so it will be easier for you to read the user's information without retrieving the "post key"
{
"profiles": {
"0059HUGgfNcEyX73ZpTi6HQUscu1": {
"email": "aaa#gmail.com",
"image": "...",
"name": "...",
"phone": "..."
},
"other user's uid": {
...
}
}
}
With this database structure, you don't need the mPostKey anymore (don't need to put and get the intent extra). To get the user's information, you can just do this
mDatabase.child(mAuth.getCurrentUser().getUid()). addValueEventListener(eventListener);
Hope my answer helps :)
To get the name of the currently logged in user from firebase simply use the following code:
String user_name=mAuth.getCurrentUser().getDisplayName();
Related
I'm using Firebase Realtime Database to store data for a project. I'm using Android Studio and Java to create a mobile app. In this particular activity, a new user is filling out a form to sign up for the service. Once they input their info and hit the submit button, the on click handles that info and inserts it into the Database.
Here is the relevant code for that class:
public class CreateUserActivity extends AppCompatActivity {
private DatabaseReference mDatabaseReference;
private List<String> mInterestList;
private EditText mUsername;
private EditText mPassword;
private EditText mEmail;
private EditText mLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_user);
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mInterestList = new ArrayList<>();
mUsername = findViewById(R.id.text_username);
mPassword = findViewById(R.id.text_password);
mEmail = findViewById(R.id.text_email);
mLocation = findViewById(R.id.text_location);
}
public void onCheckboxClicked(View view) {
CheckBox checkbox = (CheckBox) view;
boolean isChecked = checkbox.isChecked();
String interest = checkbox.getText().toString();
if(isChecked) {
mInterestList.add(interest);
}else {
mInterestList.remove(interest);
}
}
public void onSaveUser(View view) {
String username = mUsername.getText().toString();
String password = mPassword.getText().toString();
String email = mEmail.getText().toString();
String location = mLocation.getText().toString();
if(TextUtils.isEmpty(username) ||
TextUtils.isEmpty(password) ||
TextUtils.isEmpty(email) ||
TextUtils.isEmpty(location) ||
mInterestList.size() == 0) {
displayToast("Please enter values for all fields");
}else {
List<String> interests = mInterestList;
User user = new User(username, password, email, location, interests, null);
mDatabaseReference.child("users").child(username).setValue(user, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(#Nullable DatabaseError databaseError, #NonNull DatabaseReference databaseReference) {
if(databaseError != null) {
Log.e(GetTogetherApp.LOG_TAG, databaseError.getMessage());
}else{
displayToast("User created!");
}
}
});
}
}
As I've run through breakpoints the error seems to fire on this line:
mDatabaseReference.child("users").child(username).setValue()
Specifically once I try and enter into the setValue() method. The other two child() calls work to find the path as intended. I have the database reference set as a member variable, so I'm not sure why it seems to lose it at that point.
Here's a look at my database structure
Firebase Database Structure Pic
Error in Android Studio:
The error message in your screenshot is in the variable inspector in the Android Studio debugger. It means that where the error occurs, there is no variable mDatabaseReference so the debugger can't show its value. This is not the actual cause of the crash, merely the debugger telling you that it can't show you something you asked for.
You can find the actual cause of the problem by inspecting the InvocationTargetException e.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
I am trying to show user information stored in my Firebase Realtime Database to text views on a separate page but when I run, LOGCAT is is throwing the error below. I am retrieving the unique id that is stored for the user but Im guessing it is not pulling the data.
This is for a new android studio application that takes a users information stored it in the database and retrieves to a profile pulling all of the information like name, email, school, etc. I have tried changing the object of user and the verification of the user to to authentication check but to no avail. I'm guessing it's a simple fix but I am not seeing it. The error is here.
public class ProfileActivity extends AppCompatActivity {
//Firebase and Database Stuff
private FirebaseAuth mAuth;
private FirebaseUser user; // saying it is never assigned
private TextView Email;
private TextView TwoPNum;
private TextView Meal;
private TextView PantherFunds;
private TextView Expiration;
private TextView Campus;
private Button logout;
private FirebaseDatabase mFirebaseDatabase;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
// TAG
private static final String TAG = "ProfileActivity";
//declare the database reference object. This is what we use to access the database.
// KEEP AN EYE ON
private String userID = user.getUid();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
Email = (TextView) findViewById(R.id.profileEmail);
TwoPNum = (TextView) findViewById(R.id.profileUid);
Meal = (TextView) findViewById(R.id.mealsNum);
PantherFunds = (TextView) findViewById(R.id.pFundsNum);
Expiration = (TextView) findViewById(R.id.expirationDate);
Campus = (TextView) findViewById(R.id.campusText);
//declare the database reference object. This is what we use to access the database.
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = mFirebaseDatabase.getReference();
logout = (Button) findViewById(R.id.button_logout);
user = mAuth.getCurrentUser();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(FirebaseAuth firebaseAuth) {
user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
toastMessage("Successfully signed in with: " + user.getEmail());
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
toastMessage("Successfully signed out.");
}
//... I think a method declaration is meant to go here but not sure
}
};
//new stuff
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
showData(dataSnapshot);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void showData(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
UserInformation uInfo = new UserInformation();
uInfo.setName(ds.child(userID).getValue(UserInformation.class).getName()); //set the name
uInfo.setEmail(ds.child(userID).getValue(UserInformation.class).getEmail()); //set the email
uInfo.setCampus(ds.child(userID).getValue(UserInformation.class).getCampus()); //set the phone_num
uInfo.setExpiration_date(ds.child(userID).getValue(UserInformation.class).getExpiration_date());// set expiration date
uInfo.setpfunds(ds.child(userID).getValue(UserInformation.class).getpfunds()); // get pantherfunds
uInfo.setMeals(ds.child(userID).getValue(UserInformation.class).getMeals()); // get Meals
uInfo.setTwop_num(ds.child(userID).getValue(UserInformation.class).getTwop_num()); // get Meals
//display all the information
Log.d(TAG, "showData: name: " + uInfo.getName());
Log.d(TAG, "showData: email: " + uInfo.getEmail());
Log.d(TAG, "showData: campus : " + uInfo.getCampus());
Log.d(TAG, "showData: expiration_date: " + uInfo.getExpiration_date());
Log.d(TAG, "showData: pfunds: " + uInfo.getpfunds());
Log.d(TAG, "showData: : meals" + uInfo.getMeals());
Log.d(TAG, "showData: twop_num: " + uInfo.getTwop_num());
// Show Data in TextViews
Email.append(uInfo.getEmail());
TwoPNum.append(uInfo.getTwop_num());
Meal.append(String.valueOf(uInfo.getMeals()));
PantherFunds.append(String.valueOf(uInfo.getpfunds()));
Expiration.append(String.valueOf(uInfo.getExpiration_date()));
Campus.append(uInfo.getCampus());
}
}
I expect for a user to log in and their data be shown in text views but am getting this error message
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo
{com.example.hootidapp/com.example.hootidapp.ProfileActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String com.google.firebase.auth.FirebaseAuth.getUid()' on a
null object reference
and
Caused by: java.lang.NullPointerException: Attempt to invoke virtual
method 'java.lang.String com.google.firebase.auth.FirebaseAuth.getUid()'
on a null object reference
at com.example.hootidapp.ProfileActivity.<init>(ProfileActivity.java:45)
In this line of code:
user = mAuth.getCurrentUser();
getCurrentUser() returned null because no user was signed in at the time it was called, and you're using auth before the auth listener was able to get a non-null user object. Check for null before calling getUid() on user. Or, ensure that you only call it after a user object is available.
I know this question has been asked in the past. I have tried almost all of their solutions did not worked for me. Sorry for asking this again. But can someone help me fix this error.
Here is my code.
public class ProfileActivity extends AppCompatActivity {
TextView userEmail;
TextView userID;
TextView userGender;
TextView userName;
Button userLogout;
FirebaseAuth firebaseAuth;
FirebaseUser firebaseUser;
FirebaseDatabase firebaseDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
userEmail = findViewById(R.id.tvUserEmail);
userGender = findViewById(R.id.tvGender);
userName = findViewById(R.id.tvName);
userID = findViewById(R.id.tvUserID);
userLogout = findViewById(R.id.btnLogout);
firebaseAuth = FirebaseAuth.getInstance();
firebaseUser = firebaseAuth.getCurrentUser();
firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = firebaseDatabase.getReference().child(firebaseUser.getUid());
//userEmail.setText(firebaseUser.getEmail());
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String userEmailstr = dataSnapshot.child("email").getValue().toString();
String userNamestr = dataSnapshot.child("name").getValue().toString();
String userGenderstr = dataSnapshot.child("gender").getValue().toString();
String userIDstr = dataSnapshot.child("id").getValue().toString();
userEmail.setText(userEmailstr);
userGender.setText(userGenderstr);
userName.setText(userNamestr);
userID.setText(userIDstr);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(),databaseError.getMessage(),Toast.LENGTH_SHORT).show();
}
});
userLogout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FirebaseAuth.getInstance().signOut();
Intent intent = new Intent(ProfileActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
});
}}
The error is on the Datasnapshot Strings. where it is said it is on a null object reference
Here is the logcat
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
at com.example.patrick.test.ProfileActivity$1.onDataChange(ProfileActivity.java:60)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##16.0.5:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##16.0.5:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##16.0.5:55)
Here is my database
Whe you are using:
.child(firebaseUser.getUid())
It means that you are passing to the child method the id of the user that is coming from the Firebase authentication process. But passing this id will not help since in your database I see that you are having an id that is generated by the push() method and not the id from the FirebaseUser object.
So to solve this, you either pass to the child() method the correct id which is -LS3X ... 6Meg or you change the way in which you are adding the user to database by removing the push() call and use something like this:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("Accounts").child(uid).setValue(userObject);
The second solution is the recommended one. Please also don't forget to add the Accounts extra child that is missing right now from your reference.
You need to change
DatabaseReference databaseReference = firebaseDatabase.getReference().child(firebaseUser.getUid());
To
DatabaseReference databaseReference = firebaseDatabase.getReference().child("Accounts").child(firebaseUser.getUid());
You're pointing to wrong node. that doesn't contains required data.
Note:
You don't need to store push_id inside as id.
You can simply get it without storing it inside.
String userIDstr = dataSnapshot.getKey();
You need to change
DatabaseReference databaseReference = firebaseDatabase.getReference().child(firebaseUser.getUid())
To
DatabaseReference databaseReference = firebaseDatabase.getReference().child("Accounts").child(firebaseUser.getUid());
And instead of
String userEmailstr = dataSnapshot.child("email").getValue().toString();
Use
String userEmailstr = dataSnapshot.child("email").getValue(String.class);
Iam beginner with the firebase, and iam trying to insert data into the firebase, I faced a problem, that when I pressed insert button, the same data is submitted many times and it doesnt stop inserting until the run is stopped
I am using push() function but i dont know where the problem is in my code
can any one help me?
my firebase looks like this when i submitted one data
here is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fill_request_page);
Title = (EditText) findViewById(R.id.Title);
Content = (EditText) findViewById(R.id.Content);
insert =(Button) findViewById(R.id.insert);
edittxtDate =(EditText) findViewById(R.id.edittxtDate);
edittxtTime =(EditText) findViewById(R.id.edittxtTime);
edittxtExpDate=(EditText) findViewById(R.id.edittxtExpDate);
location = (Spinner) findViewById(R.id.location);
typeof=(Spinner)findViewById(R.id.typeof);
database = FirebaseDatabase.getInstance();
ref1 = database.getReference("requests");
imagebtnTime.setOnClickListener(this);
storage = FirebaseStorage.getInstance();
storageReference = storage.getReference();
private void getValues(){
request1.setTitle(Title.getText().toString());
request1.setContent(Content.getText().toString());
request1.setDate(edittxtDate.getText().toString());
request1.setTime(edittxtTime.getText().toString());
request1.setLocation(location.getSelectedItem().toString());
request1.setExpDate(edittxtExpDate.getText().toString());
request1.setTypeof(typeof.getSelectedItem().toString());
}
public void btnInsert1(View view){
ref1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DatabaseReference ref2=ref1.push();
String id=ref2.getKey();
request1 =new requests();
getValues();
ref1.child(id).setValue(request1);
Toast.makeText(FillRequestPage.this,"Data inserted....",Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
please help me
When sending data to the database, you do not need to use AddValueEventListener(..), you can just do this:
database = FirebaseDatabase.getInstance();
ref1 = database.getReference("requests");
DatabaseReference ref2=ref1.push();
String id=ref2.getKey();
request1 =new requests();
ref1.child(id).setValue(request1);
//some code may be missing
AddValueEventListener(..) is used to retrieve data from the database.
I want to get the post id in which user is currently signed in i.e in my case I need this: "-Kqm0-HrwGNgDhvTqOjU" because the current user id is "OiHtZxtLUeh63UzudUChEpSODPx2".
so that I can get the name of currently signed in user
here's my code:
public class MyAccount extends AppCompatActivity {
private Button mSetupButton;
private EditText mSetupName;
private EditText mSetupBio;
private ImageButton mSetupImageButton;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private String mPostKey=null;
private DatabaseReference mDatabase;
private FirebaseDatabase mFirebasedatabase;
private DatabaseReference myRef;
private String userId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_account);
DatabaseReference mdatabaseR = FirebaseDatabase.getInstance().getReference().child("Profiles");
mAuth = FirebaseAuth.getInstance();
mFirebasedatabase=FirebaseDatabase.getInstance();
FirebaseUser currentFirebaseUser = FirebaseAuth.getInstance().getCurrentUser() ;
//Toast.makeText(this, "" + currentFirebaseUser.getUid(), Toast.LENGTH_SHORT).show();
mSetupName = (EditText) findViewById(R.id.accountName);
mSetupBio = (EditText) findViewById(R.id.accountBio);
mSetupButton = (Button) findViewById(R.id.accountButton);
mSetupImageButton = (ImageButton) findViewById(R.id.accountImageButton);
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Profiles");
String user_id=mAuth.getCurrentUser().getUid();
DatabaseReference myRef=ref.child(user_id);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot objSnapshot: snapshot.getChildren()) {
String obj = objSnapshot.getKey();
Toast.makeText(MyAccount.this,obj, Toast.LENGTH_LONG).show();
String post_name = (String) objSnapshot.child("Name").getValue();
mSetupName.setText(post_name);
}
}
#Override
public void onCancelled(DatabaseError firebaseError) {
}
});
//Toast.makeText(MyAccount.this,user_id,Toast.LENGTH_LONG).show();
}
}
in "String obj" i'm getting all the post ids because of for loop, but in my case I only need that one in which user is signed in i.e whose uid is "OiHtZxtLUeh63UzudUChEpSODPx2"
You have to loop every object, like this:
ref.child('users').orderByChild('uid').equalTo('your_uid').on("value",
function(snapshot) {
console.log(snapshot.val());
});
There are two solutions:
Use a query to find the profile for the user
Change your JSON structure to store users under their UID (recommended)
Use a query to find the profile for the user
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Profiles");
Query query = ref.orderByChild("uid").equalTo("OiHtZxtLUeh63UzudUChEpSODPx2");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot objSnapshot: snapshot.getChildren()) {
String obj = objSnapshot.getKey();
Change your JSON structure to store users under their UID
If you have a collection of items that have a natural key, you should store those items under their natural key. So in a collection of users, store the users under their UID:
profiles
OiHtZxtLUeh63UzudUChEpSODPx2
email: "..."
name: "..."
phone: "..."
UIDofuser2
email: "..."
name: "..."
phone: "..."
This has many advantages, a few of which are:
Each UID can by definition only be present once in this structure.
It's easier to secure access to user profiles (if needed) in this scenario, as shown in the documentation
(most important for you) You can access the user without a direct read, instead of needing to query:
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Profiles");
DatabaseReference userRef = ref.child("OiHtZxtLUeh63UzudUChEpSODPx2");
userRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
String obj = objSnapshot.getKey();
In this last snippet you'll notice that the Query is no longer needed, which improves the scalability of your code. While that likely won't make a big difference on a list of users, in other cases it may. Since we do a direct read, we also no longer need the loop in onDataChange(), which improves the readability of the code.