我正在开发我的第一个应用程序,我只是设置了所有框架。 这是用户通过谷歌,电子邮件,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)
答案 0 :(得分:1)
这不是Firebase数据库异常,也不是Cloud Firestore异常。您的例外清楚地告诉您发生了什么。因此,您尝试使用findViewById()
方法on a null object reference
。这意味着getView()
会返回null
。这种情况正在发生,因为您在返回fragmnet视图后调用该方法。
为了解决这个问题,请先调用这些方法,然后直接在视图上使用findViewById()
方法。