#java #android #firebase #firebase-realtime-database #firebase-authentication
# #java #Android #firebase #firebase-база данных в реальном времени #firebase-аутентификация
Вопрос:
Я относительно новичок в реализации Fire Base. Я делал одно и то же снова и снова, и это работает, но теперь, когда я использую его, сбой. Ошибка возникает, когда я пытаюсь извлечь данные из базы данных, приложение вылетает с сообщением об ошибке нулевой точки getUid(), я опубликую ошибку ниже. Ошибка появляется после того, как я уже вошел в систему и подтвердил, что это пользователь.
Вот код:
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.HashMap;
import java.util.Objects;
import de.hdodenhof.circleimageview.CircleImageView;
public class SettingsActivity extends AppCompatActivity {
private Button UpdateAccountSettings;
private EditText UserName, UserStatus;
private CircleImageView UserProfileImage;
private FirebaseAuth mAuth;
private FirebaseUser currentUser;
private DatabaseReference RootRef;
private String currentUserID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
mAuth = FirebaseAuth.getInstance();
currentUser = mAuth.getCurrentUser();
currentUserID = currentUser.getUid();
RootRef = FirebaseDatabase.getInstance("https://chatrcsapp-default-rtdb.firebaseio.com").getReference();
IntializeFields();
UpdateAccountSettings.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UpdateSettings();
}
});
RetrieveUserInfo();
}
private void IntializeFields() {
UpdateAccountSettings = findViewById(R.id.update_settings_button);
UserName = findViewById(R.id.set_user_name);
UserStatus = findViewById(R.id.set_profile_status);
UserProfileImage = findViewById(R.id.profile_image);
}
private void UpdateSettings() {
String setUserName = UserName.getText().toString();
String setUserStatus = UserStatus.getText().toString();
if(TextUtils.isEmpty(setUserName)){
Toast.makeText(this, "Insert User Name, please...", Toast.LENGTH_SHORT).show();
}
if(TextUtils.isEmpty(setUserStatus)){
Toast.makeText(this, "Insert User Status, please...", Toast.LENGTH_SHORT).show();
}
else {
HashMap<String, String> profileMap = new HashMap<>();
profileMap.put("uid", currentUserID);
profileMap.put("name", setUserName);
profileMap.put("status", setUserStatus);
RootRef.child("Users").child(currentUserID).setValue(profileMap)
.addOnCompleteListener(task -> {
if (task.isSuccessful()){
SendUserToMainActivity();
Toast.makeText(SettingsActivity.this, "Details Added Successfully...", Toast.LENGTH_SHORT).show();
}
else {
String message = task.getException().toString();
Toast.makeText(SettingsActivity.this, "Error: " message, Toast.LENGTH_SHORT).show();
}
});
}
}
private void RetrieveUserInfo() {
RootRef.child("Users").child(currentUserID)
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if ((dataSnapshot.exists()) amp;amp; (dataSnapshot.hasChild("name") amp;amp; (dataSnapshot.hasChild("image")))){
String retrieveUserName = dataSnapshot.child("name").getValue().toString();
String retrieveUserStatus = dataSnapshot.child("status").getValue().toString();
String retrieveUserProfileImage = dataSnapshot.child("image").getValue().toString();
UserName.setText(retrieveUserName);
UserStatus.setText(retrieveUserStatus);
}
else if ((dataSnapshot.exists()) amp;amp; (dataSnapshot.hasChild("name"))){
String retrieveUserName = dataSnapshot.child("name").getValue().toString();
String retrieveUserStatus = dataSnapshot.child("status").getValue().toString();
UserName.setText(retrieveUserName);
UserStatus.setText(retrieveUserStatus);
}
else{
UserName.setVisibility(View.VISIBLE);
Toast.makeText(SettingsActivity.this, "Please Update your Information...", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void SendUserToMainActivity() {
Intent mainActivity= new Intent(SettingsActivity.this, MainActivity.class);
mainActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainActivity);
finish();
}
private void SendUserToLoginActivity() {
Intent loginIntent = new Intent(SettingsActivity.this, LoginActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(loginIntent);
finish();
}
}
И вот сообщение об ошибке:
Process: com.arthur.chatapp, PID: 8049
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.arthur.chatapp/com.arthur.chatapp.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2944)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3079)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1836)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6711)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
at com.arthur.chatapp.SettingsActivity.onCreate(SettingsActivity.java:49)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2924)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3079)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1836)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6711)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)
Комментарии:
1. Ваш CurrentUser равен null, что является обычным случаем. Прочитайте это: почему мой CurrentUser == null?
Ответ №1:
Сообщение об ошибке довольно явное:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference at com.arthur.chatapp.SettingsActivity.onCreate(SettingsActivity.java:49)
Поэтому, что бы вы ни думали, в коде whic currentUser
это действительно так null
.
currentUser = mAuth.getCurrentUser();
currentUserID = currentUser.getUid();
Скорее всего, это связано с тем, что Firebase еще не установлена mAuth.getCurrentUser()
к моменту запуска вашего кода. Чтобы предотвратить это, вы можете использовать прослушиватель состояния аутентификации, который гарантирует, что ваш код автоматически запускается при изменении состояния аутентификации:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
mAuth = FirebaseAuth.getInstance();
RootRef = FirebaseDatabase.getInstance("https://chatrcsapp-default-rtdb.firebaseio.com").getReference();
IntializeFields();
UpdateAccountSettings.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UpdateSettings();
}
});
mAuth.addAuthStateListener(new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
currentUser = mAuth.getCurrentUser();
currentUserID = currentUser.getUid();
if (user != null ) {
RetrieveUserInfo();
} else { //user is not logged in
...
}
}
});
};
}
Комментарии:
1. Спасибо за ответ, и я уже пробовал это, но приложение выполняет SettingsActivity из MainActivity, но когда я updatesettings(); он выходит из строя, что означает, что он не извлекает данные из Firebase, а запускает его как пустое действие.
2. Мой ответ сосредоточен на
SettingsActivity.onCreate
, потому что это трассировка стека в вашем вопросе. С моим ответом эта конкретная трассировка стека должна была исчезнуть. Так ли это? Если это так, это отвечает на ошибку, о которой вы сообщили в этом вопросе. Основная проблема в других местах, вероятно, такая же, как и та, которую я объяснил в своем ответе: вы не можете полагаться наgetCurrentUser()
возврат вам фактического пользователя в большинстве мест, и вам нужно будет поместить его в прослушиватель состояния аутентификации.