gpt4 book ai didi

javascript - 使用 Firebase Cloud Functions 在数据库中查找重复的用户名

转载 作者:行者123 更新时间:2023-12-01 03:23:41 24 4
gpt4 key购买 nike

按照我的建议,当新用户在使用 Firebase Cloud Functions 对用户进行身份验证之前注册时,我试图在数据库中查找重复的用户名,因为 .queryEqual(toValue) 本地不会出现”每次都工作。我现在无法理解的是如何在我的应用程序中使用它。这是我部署的云函数:

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.uniqueUsername = functions.https.onRequest((req, res) => {
const username = req.query.username
admin.database().ref('users').orderByChild('username').equalTo(username).once('value').then(snap => {
// if the child exists, then the username is taken
if (snap.exists()) {
res.send('username not available');
} else {
res.send('username available');
}
});
});

equalTo(username) 是从 UITextField 中选取的值,然后与数据库中的值进行比较。我在这里得到的错误是:

Error: Query.equalTo failed: First argument contains undefined in property 'users'
at Error (native)
at Ae (/user_code/node_modules/firebase-admin/lib/database/database.js:105:67)
at ze (/user_code/node_modules/firebase-admin/lib/database/database.js:104:400)
at W.h.Jf (/user_code/node_modules/firebase-admin/lib/database/database.js:142:60)
at exports.uniqueUsername.functions.https.onRequest (/user_code/index.js:10:60)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:26:47)
at /var/tmp/worker/worker.js:649:7
at /var/tmp/worker/worker.js:633:9
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickDomainCallback (internal/process/next_tick.js:122:9)

当我在浏览器中使用该 URL 时出现的错误是:

Error: could not handle the request

我做错了什么?接下来我应该做什么?

最佳答案

从该错误消息中,您将 undefined 值传递到 equalTo 函数中。

在执行查询(以及任何查询)之前,您想要使用 "fail-fast"方法。在本例中,如果 req.query.usernamefalsy ,返回错误。

exports.uniqueUsername = functions.https.onRequest((req, res) => {
const username = req.query.username;
if (!username) {
res.status(400).json({error: 'Missing username GET parameter'});
return;
}
// rest of your code.
}

更好的方法

对于任何需要唯一性的键,您都需要使用索引。在您的数据库中,它看起来类似于:

"/usernames": {
"bob": "userId1",
"frank": "userId2",
"c00lguy": "userId3"
}

为了检查用户名是否免费,我建议首先让用户登录并进行身份验证。这可以确保我们有一个与用户名关联的用户 ID。他们登录后,检查他们是否尚未设置用户名,如果没有,则使用某种形式的对话框/输入提示他们设置用户名。

要检查用户名的可用性并在“单个”操作中声明它,您可以调用以下代码:(在内部它不是单个操作)

var desiredUsername = '...'; // from the form.
var userId = '...'; // the current logged in user's ID (normally from user.uid)
var ref = firebase.database().ref('/usernames').child(desiredUsername);
ref.transaction(function (currentData) {
if (currentData !== null && currentData !== userId) {
return; // returns undefined. Which aborts the operation because there is data here. (someone owns that username other than the current user).
}
// if here, username is available or owned by this user.
return userId; // returning a value will write it to the database at the given location.
})
.then(function(transactionResult) {
if (transactionResult.committed) {
// username is now owned by current user
// do something
} else {
// username already taken.
// do something
}
})
.catch(function (error) {
// if here, an error has occured
// (probably a permissions error, check database rules)
// do something
});

此代码片段使用 Transaction操作允许您从数据库读取值,然后立即对其进行操作。在您的原始代码中,在您调用 uniqueUsername 函数并声明该用户名之间,其他人可以这样做。使用交易可以在用户知道用户名免费时立即声明其用户名,从而最大限度地减少执行此操作的机会窗口。

此方法比搜索数据库更快,并且允许您使用简单的查询按用户名查找用户。

以下代码是此类查询的示例,对于无人认领的用户名将返回 null

function findUserIdByUsername(username) {
if (!username) {
return Promise.reject('username is falsy');
}
firebase.database().ref('/usernames').child(username).once('value')
.then(snapshot => {
if (!snapshot.exists()) {
return null; // no user with that username
}
return snapshot.val(); // the owner's user ID
});
}

结合您的原始代码,它看起来像这样:

exports.uniqueUsername = functions.https.onRequest((req, res) => {
const username = req.query.username;
if (!username) {
res.status(400).json({error: 'Missing username GET parameter'});
return;
}
var ownerID = findUserIdByUsername(username);
res.json({taken: (ownerID !== null)}); // Returns {"taken": "true"} or {"taken": "false"}
}

关于javascript - 使用 Firebase Cloud Functions 在数据库中查找重复的用户名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44987473/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com