首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何同时从两个不同的源中添加Fi还原文档中的新字段?

如何同时从两个不同的源中添加Fi还原文档中的新字段?
EN

Stack Overflow用户
提问于 2020-04-23 06:41:21
回答 1查看 70关注 0票数 1

当一个新用户在我的应用程序中注册时,使用firebase-authentication自定义登录,使用电子邮件和密码,我需要将这些数据更新到我的防火墙中。但是Firebase只有FirebaseAuth.createUserWithEmailAndPassword(email, password)来创建一个新帐户,因此我不能同时更新我的用户的用户名

要更新Firestore中的电子邮件,我使用Firebase云函数。下面是代码:

代码语言:javascript
复制
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()之后,我立即这样做:

代码语言:javascript
复制
 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说,下面是我的代码:

代码语言:javascript
复制
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.

EN

回答 1

Stack Overflow用户

发布于 2020-04-23 06:57:45

使用事务解决来自多个客户端的冲突,这些客户端都试图修改同一个文档。如果在更改发生之前检测到文档已被修改,则事务处理程序将在客户端上重新尝试。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61380833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档