将用户添加到 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 上的视频中描述了一种可能的解决方案。他在数据库中创建了两个部分:users
和 loginQueue
。 users
中的用户只能由授权用户读取,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颤振中的所有用户文档?