Android应用程序:从实时数据库到firestore - 将数据更新到数据库

时间:2018-01-05 11:24:59

标签: android firebase firebase-realtime-database google-cloud-firestore

我正在开发我的第一个应用程序,我只是设置了所有框架。 这是用户通过谷歌,电子邮件,Facebook注册并将数据保存到Firebase。 我开始使用实时数据库,它运行良好,但对于我的项目进展,我认为FireStore Cloud更适合。

我还没有太多数据,因此很容易设置它。 用户注册或登录,如果他不存在,则根据FirebaseAuth名称+电子邮件和我定义的一些变量("昵称"," - " ),还有一些。 到目前为止都很好。一旦用户点击他的个人资料,就会获取并显示该信息。 然后有选项编辑一些数据,如昵称,年龄和国籍。 如果我直接在firestore上更新数据并再次单击配置文件,则会正确显示。 但是,如果用户输入信息并单击触发更新到Firestore云的按钮,则应用程序崩溃。但是,数据库也正确更新... 我尝试了很多东西,但我卡住了!非常感谢你的帮助!

我的代码

USER CLASS =>当用户登录时,信息一次存储到云中

public class User extends AppCompatActivity {

public static final String AGE = "Age";
public static final String EMAIL = "Email";
public static final String FULLNAME = "Full name";
public static final String NATIONALITY = "Nationality";
public static final String NICKNAME = "Nickname";
public static final String STATUS = "Status";

private String userEmail = FirebaseAuth.getInstance().getCurrentUser().getEmail();
private String userFullName = FirebaseAuth.getInstance().getCurrentUser().getDisplayName();


public User() {
    // Default constructor required for calls to DataSnapshot.getValue(User.class)
}

protected void checkFireStoreDatabase() {
    // Create a new user with a first and last name
    FirebaseFirestore db = FirebaseFirestore.getInstance();
    DocumentReference usersDocRef = db.collection("Users").document(userFullName);

    if (usersDocRef != null) {
    } else {
        createNewEntry();
    }
}

public void createNewEntry() {
    FirebaseFirestore db = FirebaseFirestore.getInstance();
    DocumentReference usersDocRef = db.collection("Users").document(userFullName);
    Map<String, Object> userEntry;

    userEntry = new HashMap<>();
    userEntry.put("Full name", userFullName);
    userEntry.put(EMAIL, userEmail);
    userEntry.put("Nickname", "-");
    userEntry.put("Age", "-");
    userEntry.put("Nationality", "-");
    userEntry.put("Status", "Baby monkey");
    db.document(userFullName).set(userEntry, SetOptions.merge()).addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            Log.d(TAG, "Document has been saved");
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Log.d(TAG, "Document could not be saved");
        }
    });
}

USER PROFILE FRAGMENT =&gt;用户可以在哪里看到存储在云中的信息

public class UserProfileFragment extends Fragment implements View.OnClickListener {
private Button btnEditProfile;

//get firestore database data
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private DocumentReference usersDocRef = db.collection("Users").document(FirebaseAuth.getInstance().getCurrentUser().getDisplayName());

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    //DATA FROM FIRESTORE
    displayFirestoreData();

    btnEditProfile = (Button) view.findViewById(R.id.edit_user_info);
    btnEditProfile.setOnClickListener(this);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_user_profile, container, false);
}

@Override
public void onClick(View v) {
    Fragment fragment = null;
    //if the button representing the "train now or create workout" fragment is clicked, create this fragment
    if (v.getId() == R.id.edit_user_info) {
        fragment = new EditUserProfileFragment();
    }
    if (fragment != null) {
        getActivity().getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment_container, fragment)
                .addToBackStack(null)
                .commit();
    }
}

public void displayFirestoreData() {
    if (usersDocRef != null) {
    }
        //this.getActivity makes sure the listener only works when in this FragmentActivity
    usersDocRef.addSnapshotListener(this.getActivity(), new EventListener<DocumentSnapshot>() {
        @Override
        public void onEvent(DocumentSnapshot documentSnapshot, FirebaseFirestoreException e) {
            if (documentSnapshot.exists()) {
                String name = documentSnapshot.getString(FULLNAME);
                String email = documentSnapshot.getString(EMAIL);
                String nickname = documentSnapshot.getString(NICKNAME);
                String age = documentSnapshot.getString(AGE);
                String nationality = documentSnapshot.getString(NATIONALITY);
                String status = documentSnapshot.getString(STATUS);

                //setting all the text views in the user profile
                TextView txtProfileName = (TextView) getView().findViewById(R.id.profile_section_fullname);
                txtProfileName.setText(name);
                TextView txtProfileEmail = (TextView) getView().findViewById(R.id.profile_section_email);
                txtProfileEmail.setText(email);
                TextView txtProfileNickname = (TextView) getView().findViewById(R.id.profile_section_nickname);
                txtProfileNickname.setText(nickname);
                TextView txtProfileAge = (TextView) getView().findViewById(R.id.profile_section_age);
                txtProfileAge.setText(age);
                TextView txtProfileNationality = (TextView) getView().findViewById(R.id.profile_section_nationality);
                txtProfileNationality.setText(nationality);
                TextView txtProfileStatus = (TextView) getView().findViewById(R.id.profile_section_status);
                txtProfileStatus.setText(status);
            } else if (e != null) {
                Log.w(TAG, "An exception occured", e);
            }
        }
    });

}

EDIT USER PROFILE FRAGMENT =&gt;用户可以输入新的昵称,年龄或国籍

    public class EditUserProfileFragment extends Fragment implements View.OnClickListener {
    private Button btnSaveProfile;

    private EditText editUsername;
    private EditText editAge;
    private EditText editNationality;

    private String username_input;
    private String age_input;
    private String nationality_input;


    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //Button to save the profile
        btnSaveProfile = (Button) view.findViewById(R.id.save_user_info);
        btnSaveProfile.setOnClickListener(this);

        //field that allows changes on the nick name
        editUsername = (EditText) view.findViewById(R.id.profile_section_edit_nickname);

        //field that allows you to enter the correct age
        editAge = (EditText) view.findViewById(R.id.profile_section_edit_age);

        //field that allows you to enter your nationality
        editNationality = (EditText) view.findViewById(R.id.profile_section_edit_nationality);

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_user_profile_edit, container, false);
    }

    @Override
    public void onClick(View v) {
        username_input=  editUsername.getText().toString().trim();
        age_input = editAge.getText().toString().trim();
        nationality_input = editNationality.getText().toString().trim();

        //update Firestore data
        updateFireStoreData(username_input, age_input, nationality_input);
       }

    //update the user entered information to the database, if the strings arent empty
    public void updateFireStoreData(String nicknameUpdate, String ageUpdate, String nationalityUpdate) {
       FirebaseFirestore db = FirebaseFirestore.getInstance();
       FirebaseUser currUser = FirebaseAuth.getInstance().getCurrentUser();
       DocumentReference userDocRef = db.collection("Users").document(currUser.getDisplayName());

        if (!nicknameUpdate.matches("")) {
            Map<String, Object> dataUpdate = new HashMap<String, Object>();
            dataUpdate.put(NICKNAME, nicknameUpdate);
            userDocRef
                    .set(dataUpdate, SetOptions.merge()).addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    Log.d(TAG, "Document has been saved");
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.d(TAG, "Document could not be saved");
                }
            });
        }
}

错误日志:

  

E / AndroidRuntime:致命异常:主要                     过程:MYAPP,PID:3992                     java.lang.NullPointerException:尝试调用虚方法&#39; android.view.View android.view.View.findViewById(int)&#39;   在null对象引用上                         at MYAPP.UserProfileFragment $ 1.onEvent(UserProfileFragment.java:103)                         at MYAPP.UserProfileFragment $ 1.onEvent(UserProfileFragment.java:91)                         在com.google.firebase.firestore.DocumentReference.zza(未知来源:45)                         在com.google.firebase.firestore.zzd.onEvent(未知来源:6)                         在com.google.android.gms.internal.zzevc.zza(未知来源:6)                         在com.google.android.gms.internal.zzevd.run(未知来源:6)                         在android.os.Handler.handleCallback(Handler.java:789)                         在android.os.Handler.dispatchMessage(Handler.java:98)                         在android.os.Looper.loop(Looper.java:251)                         在android.app.ActivityThread.main(ActivityThread.java:6563)                         at java.lang.reflect.Method.invoke(Native Method)                         在com.android.internal.os.Zygote $ MethodAndArgsCaller.run(Zygote.java:240)                         在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

1 个答案:

答案 0 :(得分:1)

这不是Firebase数据库异常,也不是Cloud Firestore异常。您的例外清楚地告诉您发生了什么。因此,您尝试使用findViewById()方法on a null object reference。这意味着getView()会返回null。这种情况正在发生,因为您在返回fragmnet视图后调用该方法。

为了解决这个问题,请先调用这些方法,然后直接在视图上使用findViewById()方法。