更新在Firebase中创建的集合(使用云功能)
请注意,以下方案使用Cloud Firestore。更新在Firebase中创建的集合(使用云功能)
在我的云功能index.js
,我有一个函数,createUserAccount
,增加了一个新创建的用户到users
收集,并为他们的电子邮件,照片,收藏领域(这是不需要的应用功能详细阐述)以及用户的其他不同领域。
// The following method has been simplified to focus on the problem statement
public void createAccountWithEmailAndPassword(String username, String displayName,
String someOtherImportantThing) {
mFirebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(getActivity(), task -> {
if (task.isSuccessful()) {
Log.d(TAG, "createUserWithEmail:Success");
onSuccess.updateAccount(displayName, username);
updateUsernameProperty(username);
onBackPressed();
} else {
if (task.getException() != null) {
if (task.getException()
.getMessage()
.contains(EMAIL_EXISTS_ERROR)) {
// Handle Email Exists Error
}
}
Log.w(TAG, "createUserWithEmail:failure",
task.getException());
}
});
}
正如你可以看到,当任务成功完成了几个方法被称为:该功能在下面的代码片段成功完成后触发updateUsernameProperty(String username)
和updateAccount(String displayName, username)
updateAccount(String displayName)
需要选择一个用户displayName并将其作为字段添加到用户帐户。 这不会对用户集合进行更改 - 仅限于已验证的帐户。
updateUsernameProperty(String username)
以用户选择的用户名和将此属性设置为用户文档内的字段。下面是代码示例,因为它可能被证明有助于理解我的问题:
private void updateUsernameProperty(String username) {
DocumentReference docRef = mFirestore
.collection(TABLE_USERS)
.document(mFirebaseAuth.getUid());
docRef.update(USERNAME_KEY, username)
.addOnSuccessListener(aVoid -> Log.d(TAG, "Username DocumentSnapshot Successful"))
.addOnFailureListener(e -> Log.e(TAG, "Error Updating Document: user/uid/username", e));
}
(到集合的典型路径是“用户/ {用户id} /用户名”)
的问题:尝试更新用户文档中的用户名字段时,云功能createUserAccount
尚未完成向数据库创建/添加新用户文档(即异步问题)。
我已经考虑使用rxJava2来帮助缓解这个问题,但我似乎无法包装我的头如何做到这一点。任何帮助是极大的赞赏。
如果您需要澄清一些事情,我会尽我所能提供所需的信息。
如果我理解正确的话,您有以下流程:
- 你叫
createUserWithEmailAndPassword
- 云功能揭开序幕,并写入一些用户信息,以公司的FireStore
- 本地,您尝试更新用户信息包括 用户名。
但是,步骤2和步骤3是竞争条件,因为当您在客户端上发布更新时,云功能可能无法完成。
问题是update()
调用取决于现有的文档。如果您在客户端代码和云端功能中使用set()
呼叫与merge
选项,则可以避免这种情况。
云功能
function createUserDoc(userId, data) {
var userRef = db.collection('users').doc(userId);
// Set the user document, creating it if it does not exist
// and merging with existing data if it does
return userRef.set(data, { merge: true });
}
的Android代码
public void updateUsername(userId, username) {
Map<String, Object> data = new HashMap<>();
data.put("username", username);
db.collection("users").document(userId)
.set(data, SetOptions.merge());
}
是的,这肯定是问题,而这个作品!我可以问你的意见: 我的应用程序允许用户创建一个唯一的用户名,并将这个值存储在一个随机UID的“用户名”集合中。然后,我添加两个字段,所有者的UID与实际用户名相匹配的“用户”文档和名称值。在“用户”文档中,我使用“用户名”集合中用户名的UID值更新了“用户名”字段。当我需要检查帐户创建时是否有用户名时,此方法是否有效? –
@NP我不太了解你的情况,我认为这将是最简单的,如果你问这个关于StackOverflow的新问题(我会很乐意回答) –
我想知道是否有一种方法来查询所有集合中的可用文档。 (例如,存储在用户名集合中的所有文档只存储唯一的用户名)。 –