如我建议的那样,在.queryEqual(toValue)使用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

我究竟做错了什么? 接下来我该怎么办?

===============>>#1 票数:2

从该错误消息中,您正在将一个undefined的值传递给equalTo函数。

在执行查询(以及任何查询)之前,您要使用“快速失败”方法。 在这种情况下,如果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).on('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"}
}

  ask by waseefakhtar translate from so

未解决问题?本站智能推荐: