首页 > 解决方案 > Firestore 数据库中的唯一字段 + Flutter

问题描述

我正在尝试在我的应用程序中实现一个正常的身份验证系统,但我想为每个用户创建一个新字段,即“uniqueName”,以便用户可以在他们的朋友列表中搜索和添加彼此。我正在考虑在 uniqueName 的注册表单中添加一个 textField 并以这种方式更新我的 User 类添加一个新字符串:

class User {
  String email;
  String name;
  String uniqueName;
  String userID;
  String profilePictureURL;
  String appIdentifier;

  ...
}

现在,因为我有这种用于电子邮件和密码注册的方法:

static firebaseSignUpWithEmailAndPassword(String emailAddress,String password,File? image,String name,) async {
try {
  auth.UserCredential result = await auth.FirebaseAuth.instance
      .createUserWithEmailAndPassword(
          email: emailAddress, password: password);
  String profilePicUrl = '';
  if (image != null) {
    await updateProgress('Uploading image, Please wait...');
    profilePicUrl =
        await uploadUserImageToFireStorage(image, result.user?.uid ?? '');
  }
  User user = User(
      email: emailAddress,
      name: name,
      userID: result.user?.uid ?? '',
      profilePictureURL: profilePicUrl);
  String? errorMessage = await firebaseCreateNewUser(user);
  if (errorMessage == null) {
    return user;
  } else {
    return 'Couldn\'t sign up for firebase, Please try again.';
  }
}

我如何修改它才能在注册中添加这个新字段?由于在数据库中创建新用户之前,我必须检查用户插入的 uniqueName 是否有效,我该怎么办?

此外,我认为如果在填写表格的同时进行此检查会很酷,我该怎么做?(这不是必需的)

谢谢大家的回答

标签: firebasefluttergoogle-cloud-firestorefirebase-authentication

解决方案


我建议执行以下步骤:

  1. 在 Firestore 中创建您自己的用户集合(例如users),您可能已经这样做了。(我认为这User不是一个好的类名,因为 Firebase 身份验证使用的是相同的名称。试试吧MyUser。)

  2. 添加身份验证触发器,以确保无论何时添加或删除 Firebase 用户,它也会被添加到集合中或从users集合中删除,使用 Firebaseuid作为标识符。

  3. 创建一个解决方案来检查集合uniqueName中是否已经存在。您可以使用 Firestore 查询,但在这种情况下,您必须至少users允许未经身份验证的访问 read字段。(因为此时用户尚未经过身份验证。)Firebase Cloud Function 是另一种选择。usersuniqueName

  4. 当用户输入他们想要uniqueName的 时,在创建 Firebase 用户之前运行检查。您可以在用户输入此内容或开始注册过程时执行此操作。

  5. 如果uniqueName是唯一的,您可以尝试创建 Firebase 用户。请注意,此步骤也可能失败(例如,电子邮件名称被占用等)。您的users文档将由您在步骤 2 中设置的身份验证触发器创建。

  6. 最后,您必须将其存储uniqueNameusers集合中。此时您将拥有uid新创建的 Firebase 用户,因此您可以使用 Firestoreset命令并将merge选项设置为true,这样您就不会覆盖其他数据。

需要注意的是,您不能保证 Firebase 触发器在users您到达第 6 点时已经创建了新文档,很可能触发器仍在工作或尚未启动。这就是为什么您必须set在身份验证触发器和您自己的代码中使用设置uniqueName:首先“到达”,将创建文档,第二个将更新它。

users此外,出于同样的原因,您必须允许使用 Firestore 规则在集合中插入和更新。这听起来可能有点吓人,但请记住,这只是您自己要跟踪的用户列表uniqueName,身份验证不是基于此,而是基于 Firebase Authentication 的用户管理,它受到了很好的保护。

最后评论:这不是 100% 的解决方案。uniqueName在您检查它是否是唯一的和实际创建用户之间保留一些其他人是不太可能的,但理论上可能会发生这种情况。为了缓解这种情况,最好在创建 Firebase 用户之前进行检查。即使在这种情况下,重复的机会仍然很小。


推荐阅读