Я продолжаю получать java.lang.Строка com.google.firebase.auth.Ошибка FirebaseUser.getUid(), хотя он уже подтвердил, что является пользователем

#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() возврат вам фактического пользователя в большинстве мест, и вам нужно будет поместить его в прослушиватель состояния аутентификации.