当一个新用户在我的应用程序中注册时,使用firebase-authentication自定义登录,使用电子邮件和密码,我需要将这些数据更新到我的防火墙中。但是Firebase只有FirebaseAuth.createUserWithEmailAndPassword(email, password)来创建一个新帐户,因此我不能同时更新我的用户的用户名。
要更新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})
}) 好的,现在我已经成功地更新了在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在云函数更新的文档中出现,云函数延迟了创建文档,这样用户的设备就可以轻松地更新用户名。
我不能在我的应用程序中使用.SET而不是.update(),因为如果我使用.set()和云函数,首先创建电子邮件和timeCreated字段。然后,该设备将删除它们,并将用户名和phoneModel。
那我该怎么做呢?
我可以在下一个活动中强行延迟更新用户名,以便云功能有足够的时间来完成他们的工作,但是我的signUpActivity要求用户名以及电子邮件和密码编辑文本。我不想为此创建一个单独的活动。
当我的数据存储在实时数据库中时,我经常使用.update(),即使路径不存在,它也用来创建子数据。但是,如果这个字段不存在,它看起来就不会更新。
有什么解决办法吗?
我试过了@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.
发布于 2020-04-23 06:57:45
使用事务解决来自多个客户端的冲突,这些客户端都试图修改同一个文档。如果在更改发生之前检测到文档已被修改,则事务处理程序将在客户端上重新尝试。
https://stackoverflow.com/questions/61380833
复制相似问题