我有一个场景,我需要使用
Auth
创建用户并向 Firestore 数据库添加更多信息(例如名称和业务类型)。 Firestore 作为事务/批量操作,但仅适用于 Firestore。
有没有一种方法可以执行
Auth
操作,例如创建以及 Firestore 数据插入。两个操作都必须成功或失败。现在我把它们链接起来,但我担心一个会失败,另一个会成功,需要优雅地处理。
谢谢你
在实施 Firebase 身份验证时,您可以使用
addOnCompleteListener
或 addOnSuccessListener
并实施 isComplete()
或 isSuccessful()
方法。在其中一种方法中,您需要在 Firestore 数据库中创建用户。换句话说,只有身份验证成功后,您才会创建用户。因此,如果 isSuccessful()
这些方法之一下的所有操作都成功,或者没有应用任何操作。
这两种方法之间的区别在于,当任务代表的工作完成时,我们可以认为该任务是
complete
,无论其成功还是失败。可能有错误,也可能没有错误,但我们需要检查一下。当任务所代表的工作按预期完成且没有错误时,任务是 successful
。
总而言之,没有办法有一个批量的解决方案。这是因为有 2 个单独的操作。因此,为了能够在数据库中写入用户详细信息,您需要首先成功进行身份验证。如果您想要回滚,则在将用户详细信息写入数据库时需要再次使用 addOnCompleteListener。如果出现错误,只需让用户退出即可。没有事务/批处理操作可以处理您所描述的身份验证和数据库写入操作。
编辑:
既然您说您正在使用 Firebase 身份验证,那么您还可以使用在 Cloud Function 中编写的函数来实现您的目标。您可以编写一个函数,该函数将在项目中每次发生某些情况时运行。这些“事情”之一就是创建用户。换句话说,您可以在每次创建新用户时执行您的逻辑。这是一个例子:
exports.updateUserCount = functions.auth.user().onCreate((user) => {
//Do what you need to do
});
此外,您可以对用户删除执行相同的操作,但使用
onDelete()
方法注册功能。
这会非常快,因为没有与用户设备的交互。请查看有关 Firebase Cloud Functions 的更多信息。
执行此类场景的最佳方法是使用
Firebase Cloud Functions
。云函数在各种创建/更新/删除/写入操作上触发。您可以在创建新用户时触发云函数,然后在其中进行相关的 Auth
创建。
https://firebase.google.com/docs/firestore/extend-with-functions
因此,在这种情况下,您首先创建用户数据,并在成功后调用 Firebase Auth 用户创建。如果您担心失败情况,可以删除创建的用户,以防身份验证创建失败。
我通过使用云函数创建auth用户和firestore文档解决了这个问题。这样您就可以轻松获得创建用户所需的一些附加数据,例如邀请代码或类似的内容。
export const signUp = functions.https.onCall(async (data, context) => {
const email = data.email;
const password = data.password;
const firstName = data.firstName;
const lastName = data.lastName;
const inviteCode = data.inviteCode;
const userRecord = await admin.auth().createUser({
email: email,
displayName: (firstName && lastName) ? (firstName + ' ' + lastName) : (firstName ?? lastName),
password: password
});
await admin.firestore().collection(constants.COLL_USERS).doc(userRecord.uid).set({
inviteCode: inviteCode
})
});
如果您同时想要进行身份验证,还想将其他详细信息保存在FireStore中,那么您也可以这样做。
如果让电子邮件= emailTextfield.text,让密码=passwordTextfield.text,让发件人姓名= nameTextField.text {
Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
if let e = error {
self.showAlert(e.localizedDescription)
}
else{
self.db.collection(K.FStore.registeredDetails).addDocument(data: [K.FStore.registeredName : sendername,
K.FStore.registeredEmail : self.emailTextfield.text!
])
self.performSegue(withIdentifier: K.registerSegue, sender: self)
}
}
}