簡體   English   中英

具有Google Cloud功能的Firebase-實時數據庫驗證以檢查尚未使用的用戶名

[英]Firebase with Google Cloud Function - Realtime Database Validation to check username not already taken

我發現其他各種帖子似乎都使我相信我的實現應該可以正常工作,但是仍然缺少一些東西。

這是我的Firebase Realtime數據庫規則:

"usernames": {
  ".read" : true,
  ".write" : "auth !== null",
  "$username":{
    ".validate": "!root.child('usernames').hasChild($username)"
  }
}

在我的用戶名節點內,例如:

"usernames"
|---"johnDoe123" : "XrG34odsfla82343174094389"
|--- etc.....

我有一個通過傳遞令牌來調用的雲函數,並且當雲函數運行時,它會嘗試通過添加新請求的用戶名(假設用戶名尚未使用)來更新“用戶名”節點。

這是我正在使用的函數部分,該部分寫入Firebase用戶名節點:

let newUser = {}
newUser[req.query.username] = decoded.uid
admin.database()
 .ref('usernames')
 .update(newUser)
 .then(() => {
  console.log(`New username <${req.query.username}> added`)
   res.status(200).send(decoded)
 }).catch(e=>{
  console.log('Error', e)
 })

雲功能正在更新用戶名節點,但是我的問題是,如果另一個子節點具有相同的用戶名,我需要讓它拒絕通過驗證進行的更新。 到目前為止,盡管有另一個具有相同確切用戶名的子節點與另一個uid關聯,但我的規則仍繼續允許進行更新。

有什么想法我做錯了嗎?

不知道這是否是最好的方法,但是它對我來說是有用的,即檢查用戶第一次在我的應用程序中進行設置以確定是否已經使用了所請求的用戶名。 如果是這樣,它將發回已采取的JSON響應。 如果未使用它,那么它將創建記錄,然后發送回成功的JSON響應。

module.exports = functions.https.onRequest((req, res) => {
  cors(req, res, () => {
    const tokenId = req.get('Authorization').split('Bearer ')[1];
    return admin.auth().verifyIdToken(tokenId)
        .then((decoded) => {
            admin.database()
            .ref('usernames')
            .child(req.query.username)
            .once('value', function(snapshot) {
                if(snapshot.val() === null){
                    let newUser = {}
                    newUser[req.query.username] = decoded.uid
                    admin.database()
                    .ref('usernames')
                    .update(newUser)
                    .then(() => {
                        console.log(`New username <${req.query.username}> added`)
                        res.status(200).send({
                            success: true,
                            message: "Username created" 
                        })
                    }).catch(err=>{
                        res.status(500).send(err)
                    })                    
                }
                else{
                    res.status(200).send({
                        success: false,
                        message: "Username already taken"
                    })
                }
            });
        })
        .catch((err) => {
            res.status(401).send(err)
        });
  })
});

如果您使用Firebase身份驗證注冊所有用戶,則該系統將自動告訴用戶,他們用來注冊的電子郵件地址已經是一個帳戶。

您還可以將用戶名作為樹路徑的一部分/ users / AUserName,以便在查詢時返回null

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM