Когда новый пользователь регистрируется в моем приложении, используя firebase-authentication
пользовательский вход, используя электронную почту и пароль, мне необходимо обновить эти данные в моем пожарном депо. Но у Firebase есть только FirebaseAuth.createUserWithEmailAndPassword(email, password)
для создания новой учетной записи, и поэтому я не могу обновить username моего пользователя одновременно.
Для обновления электронной почты в Firestore я использую облачные функции Firebase. Вот код:
export const onNewUserJoined = functions.auth.user().onCreate((user) => {
//const newUserDisplayName = user.displayName //CAN'T USE THIS. REASON is BELOW
const newUserUID = user.uid
const newUserEmail = user.email
const timeCreated = Date.now()
console.log(`${newUserUID} has joined.`)
return admin.firestore().collection('Agent').doc(`${newUserUID}`).set({"E-Mail": newUserEmail, "Time": timeCreated})
})
Хорошо, отлично, теперь я успешно обновил E-Mail и время, созданное в Firestore.
Но следующая задача - мне нужно обновить имя пользователя в тот же документ Firestore. Я делаю это сразу после createUserWithEmailAndPassword()
, например:
DocumentReference dDocRef = FirebaseFirestore.getInstance().document(documentPath);
Map<String, Object> updateUsernameAndPhone = new HashMap<>();
updateUsernameAndPhone.put("username", username);
updateUsernameAndPhone.put("phoneData", phoneModel);
dDocRef.update(updateUsernameAndPhone).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Toast.makeText(getApplicationContext(), "Data successfully stored in Firestore", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
});
Теперь все зависит от того, кто действует первым, облачная функция или устройство пользователя.
Если сначала действуют облачные функции, то проблем нет. И имя пользователя, и phoneModel успешно обновляются в документе. Нет проблем.
Но в случае, если сначала телефон работает, то я получаю следующую ошибку:
Поскольку эта ошибка произошла, имя пользователя отсутствует в документе, и только электронная почта и timeCreated находятся в документе, обновленном облачной функцией, которая запоздала с созданием документа, чтобы пользовательское устройство могло легко обновить имя пользователя.
I CAN ' T использует .SET
вместо .update()
в моем приложении, потому что, если я использую .set()
и облачные функции, сначала создайте поля email и timeCreated. Затем устройство удалит их и поместит имя пользователя и phoneModel.
Так как я могу это сделать?
Я могу принудительно отложить обновление имени пользователя, поместив его в следующее действие, чтобы облачные функции получили достаточно времени, чтобы выполнить свою работу, но мой signUpActivity
запрашивает имя пользователя вместе с электронной почтой и паролем для редактирования текстов. Я не хочу создавать отдельную деятельность для этого.
Раньше я использовал .update()
, когда мои данные хранились в базе данных реального времени и использовались для создания дочернего элемента, даже если путь не существовал. Но похоже, что Firestore не будет обновляться, если поле не существует.
Есть какое-нибудь решение для этого?
Я пытался, как сказал @DougStevenson, и вот мой код:
final String newUserUID = Objects.requireNonNull(signUpAuth.getCurrentUser()).getUid();
final String documentPath = "Agent/" + newUserUID;
FirebaseFirestore fFirestoreRef = FirebaseFirestore.getInstance();
final DocumentReference dDocRef = fFirestoreRef.document(documentPath);
fFirestoreRef.runTransaction(new Transaction.Function<Void>() {
@Nullable
@Override
public Void apply(@NonNull Transaction transaction) throws
FirebaseFirestoreException {
DocumentSnapshot documentSnapshot = transaction.get(dDocRef);
transaction.update(dDocRef, "username", username);
transaction.update(dDocRef, "phoneData", phoneModel);
return null;
}
}).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Toast.makeText(getApplicationContext(), "Data updated in Firestore . . .", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
});
Но не повезло. Это все еще дает мне ошибку: Cannot update a document which does not exist.