error with Nullpointer exeption string in datasnapshot - java

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);

Related

Firebase Database Reference Error: No such instance field: 'mDatabaseReference'

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.

How can I retrieve data from Firebase Realtime Database in two different activity

I'm setting up an android apps that could show the personal data in two different activity. The data is stored in my firebase database, can anyone help me doing that?
I already tried to use addValueEventListener in both of my java classes. User's class that is responsible to display user information in User Profile activity is successfully retrieved the data from my firebase, but the other one still couldn't retrieve the data from my firebase.
This is the code from java class that couldn't retrieve the data from my firebase.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_land_profile);
mAuth = FirebaseAuth.getInstance();
mUser = mAuth.getCurrentUser();
mDBase = FirebaseDatabase.getInstance();
nama_lahan = (TextView) findViewById(R.id.nama_lahan);
lebar_lahan = (TextView) findViewById(R.id.lebar_lahan);
panjang_lahan = (TextView) findViewById(R.id.panjang_lahan);
luas_lahan = (TextView) findViewById(R.id.luas_lahan);
jenis_lahan = (TextView) findViewById(R.id.jenis_lahan);
jenis_pupuk = (TextView) findViewById(R.id.jenis_pupuk);
public void fetchLandData (String userUID){
mAkun = mDBase.getReference("Akun").child(userUID);
mAkun.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot landData : dataSnapshot.getChildren()){
Lahan lahan = landData.getValue(Lahan.class);
if(lahan != null){
namaLahan = lahan.getNamaLahan();
jns_lahan = lahan.getJenisLahan();
jns_pupuk = lahan.getJenisPupuk();
lebarLahan = lahan.getLebarLahan();
panjangLahan = lahan.getPanjangLahan();
luasLahan = panjangLahan*lebarLahan;
nama_lahan.setText(namaLahan);
jenis_pupuk.setText(jns_pupuk);
jenis_lahan.setText(jns_lahan);
lebar_lahan.setText(String.valueOf(lebarLahan));
panjang_lahan.setText(String.valueOf(panjangLahan));
luas_lahan.setText(String.valueOf(luasLahan));
}else{
Toast.makeText(LandProfileActivity.this, "Gak iso pisan ``bos", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
While the other one is pretty much the same structure but different variable name and it could give me the result that i wanted.
That is the screenshot from my application that failed to retrieve data from my firebase and
This is what my Firebase DB looks like
These are some error that i copied from my logcat :
2019-02-09 23:32:11.070 1645-3271/? E/ActivityTrigger: activityStartTrigger: not whiteListedcom.example.johno.test/com.example.johno.test.LandProfileActivity/1
2019-02-09 23:32:11.072 1645-3271/? E/ActivityTrigger: activityResumeTrigger: not whiteListedcom.example.johno.test/com.example.johno.test.LandProfileActivity/1
2019-02-09 23:32:11.079 1645-3065/? E/ActivityTrigger: activityResumeTrigger: not whiteListedcom.example.johno.test/com.example.johno.test.LandProfileActivity/1
you can put Firebase ValueEvent listener in Application class:
public class MyApplication extends Application {
//mAkun field declaration;
private ValueEventListener value_event_listener;
#Override
public void onCreate() {
mAkun = mDBase.getReference("Akun").child(userUID);
mAkun.addValueEventListener(new ValueEventListener() {/*..*/}
}
#Override
public void onTerminate() {
super.onTerminate();
mAkun.removeEventListener(value_event_listener);
}
}

When I am inserting data in firebase, the data is submitted unlimited time till the run is stopped-android studio

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 Name of currently logged in user from firebase

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();

how to get key of post in which user is currently signed in

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.

Categories

Resources