将用户添加到 Firebase 数据库

Posted

技术标签:

【中文标题】将用户添加到 Firebase 数据库【英文标题】:Adding users to Firebase Database 【发布时间】:2017-12-28 21:29:03 【问题描述】:

我正在学习 Firebase 并使用它创建我的第一个项目。我正在使用 FirebaseUI 来简化身份验证。我现在正在处理数据库,我需要首先将经过身份验证的用户添加到其中。我已经阅读了所有文档并且能够做到这一点,但我想知道我是否以最好的方式做到这一点。

由于我使用的是 FirebaseUI,而我自己并没有真正调用 Firebase 身份验证的 signIn()createUser() 方法,我认为添加用户的最佳方法是这样做 onAuthStateChanged()

usersRef = rootRef.child('users')

firebase.auth().onAuthStateChanged(user => 
  if (user) 
    let userRef = usersRef.child(user.uid)
    userRef.set(
      name: user.displayName,
      email: user.email,
      photoURL: user.photoURL,
      emailVerified: user.emailVerified,
    )
  

这很好用,但我担心两件事:

1) 这会在每次用户通过身份验证时设置用户数据,即使用户已经存在并且没有任何更改。一个简单的页面重新加载会将用户重写到数据库中。

2) 为了使其工作,userRef 位置需要用户可写。这意味着 userRef 位置中的 emailVerified 不可靠,因为用户可能自己修改它。我可以只依赖从onAuthStateChanged 返回的emailVerified,用户永远无法修改它,但我想知道是我做错了还是有更好的方法。

https://www.youtube.com/watch?v=QEd2lEoXpp40 上的视频中描述了一种可能的解决方案。他在数据库中创建了两个部分:usersloginQueueusers 中的用户只能由授权用户读取,loginQueue 只能由授权用户写入。当用户通过身份验证时,他的数据被写入loginQueue。然后,他使用on() 方法检查添加到loginQueue 中与他们的user.uid 匹配的孩子,并以某种方式使用update 方法将用户数据写入users。这有效,但我不明白如何。如果 update() 只是可读的,客户端如何能够将 update() 发送到 users\uid?您可以在视频中的 7:00 看到他的代码。这让我很难过。这行得通,但为什么。

我刚刚实现了视频中显示的技术,虽然它对他有用,但在尝试更新唯一可读的用户数据时遇到了PERMISSION_DENIED 错误。这是我认为应该发生的事情,但在他的视频中,他清楚地表明这没有发生。除非我遗漏了一些我认为不是的东西,否则他的方法不再起作用。也许这是后来修复的错误?

更新:感谢 Doug Stevenson 向我介绍 Firebase Cloud Functions。通过创建一个在新用户通过身份验证时响应的云功能,我能够完全解决我的问题。这是我的代码:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.addUserToDB = functions.auth.user().onCreate(event => 
  admin.database().ref('/users/' + event.data.uid).set(
    name: event.data.displayName,
    email: event.data.email
  );
);

【问题讨论】:

【参考方案1】:

这是一种常见的策略。

    身份验证不应过于频繁。此外,如果自上次写入以来用户记录中没有任何变化,则实际上什么都不会发生。您无需为客户端写入数据库的带宽付费。

    将您的用户数据分成两部分,一部分可由当前 UID 写入,另一部分不可写入。这将防止用户修改您不希望他们修改的数据时出现问题。

除此之外,在您的数据库中留出另一个位置,您的客户可以在该位置推送命令以更新其他地方的数据,并使用Cloud Functions for Firebase 触发器来读取这些命令,以提升的权限对它们进行操作,检查正确性并删除他们。

【讨论】:

1) 为什么set() 写不会发生?如果数据相同,我从来没有读过关于set() 不写的任何内容。据我了解,它总是写入和覆盖。即使它在没有任何改变的情况下写入,我想这不是一个大问题,但它让我想知道是否有更好的方法。 2) 我看了一个视频,有人这样做了。当 auth 状态改变时,他将用户数据保存到 LoginQueue 引用中,然后用on() 监听child_added。当它检测到一个孩子被添加到 LoginQueue 时,它​​会将用户添加到 Users 引用并将其从 LoginQueue 中删除。他使用户数据只可读,而 loginQueue 数据只可写。我不明白他是如何在on() 期间写入用户数据的,因为它只是可读的,但它有效。但即便如此,用户仍然可以通过修改 LoginQueue 来更改 emailVerified Cloud Functions 更加简洁,可以让您在后端隔离敏感代码,在所有类型的客户端之间统一。我在这里概述了这个策略(在一个简单的网页游戏的背景下):youtu.be/eWj6dxfN63g?t=11m31s 这让我很难过。如果您在 howtofirebase.com/firebase-data-modeling-939585ade7f4 的视频中转到 7:00,您将在右侧看到他的规则,在左侧看到他的代码。如果dataaccountsRef指向的数据被标记为只读,他怎么可能更新accountsRef上的user 我将不得不了解你们正在谈论的这些云功能。总是有更多的东西要学!

以上是关于将用户添加到 Firebase 数据库的主要内容,如果未能解决你的问题,请参考以下文章

将用户添加到 Firebase 数据库

注册时如何将用户名添加到 Firebase 数据库?

反应原生 firebase 创建用户,然后将其他数据添加到实时数据库

如何将数据作为子集合添加到firebase颤振中的所有用户文档?

如何在用户离线时尝试将数据添加/上传到 Firebase 时显示错误?

将所有数据从Firebase数据库导入Mailchimp