【问题标题】:How do I query Firebase using Typescript?如何使用 Typescript 查询 Firebase?
【发布时间】:2026-01-29 18:30:01
【问题描述】:

我使用 Firebase Cloud Functions 为我的应用设置了推送通知。它运作良好。现在我想更新应用程序的徽章计数作为推送通知的一部分。我读过唯一的方法是通过服务器端代码。我不能在本地做。

所以我试图从服务器获取新用户的数量,然后在发送推送通知时将该数字用作徽章计数,但我不知道如何去做。我已经花了三天时间,现在我希望有人能指出我正确的方向。

我正在使用 Firebase 函数和 Typescript(带有 VSCode)。我的做法是:

  1. 从 'admin' 节点获取用户 ID 列表
  2. 遍历 'user' 节点上的那些用户 ID 以查询用户的 'newUser' 参数是否为真
  3. 将这些结果附加到数组中
  4. 对数组进行计数,然后将其发送到推送通知中的徽章

我的“用户”数据库结构是这样的:

"users": {

  "2NBvNgdNRVe3nccTEDts2Xseboma": {

    "email": "someone@someone.com"

    "newUser": "true",

    "referral": "none",

    ...

  },

  "hjC6os6wzIV1FyULmGxalU3fM7ef": {

    "email": "someoneElse@someone.com"

    "newUser": "false",

    "referral": "Bennett",

    ...

  }

我的“管理员”数据库的结构如下:

"admin": {

  "2NBvNgdNRVe3nccTEDts2Xseboma": {

    "email": "someone@someone.com"

    "familyName": "Someone",

    "memberSince": "1529119893",

  },

  "hjC6os6wzIV1FyULmGxalU3fM7ef": {

    "email": "someoneElse@someone.com"

    "familyName": "Someone Else",

    "memberSince": "1529125722",

    ...

  }

这是我编写此代码的微弱尝试:

exports.getNewUserCount =

functions.database.ref('/users/{userID}/newUser')

    .onUpdate((snapshot, _context) => {

        console.log('test 2')

        // Get a database reference

        const db = admin.database();
        const ref = db.ref('admin');


        return ref.once('value', function(adminSnap) {

            const userData = adminSnap.val()

            console.log('admin key:', adminSnap.key)
            console.log('user data:', userData)

        })

    });

现在我一直在从管理节点检索用户列表(我上面的第 1 步)。

更新

我终于得到了一个用户列表作为快照,但我不知道如何迭代它们。如何将快照转换为用户键数组?

然后,一旦我获得了用户密钥列表,那么我如何使用它来遍历“用户”节点以获取新用户列表(我上面的第 2 步)?

然后如何将这些新用户放入一个数组中(我上面的第 3 步),然后在我发送推送通知时获取 'badge' 参数的新用户数量(我上面的第 4 步)?

问题是这看起来效率很低。必须有更好的方法来简单地获取新用户列表。必须有某种我可以执行的查询将遍历我的“用户”节点,查看哪些对于他们的“新用户”节点具有“真实”,并计算这些 - 而不是我的迂回获取方式来自“admin”节点的用户列表,然后使用该列表从“users”节点获取“新用户”列表,然后创建一个数组,然后对该数组进行计数,然后使用该数字发送到“徽章” ' 我的推送通知中的参数。

有什么想法吗?我已经在这几天了。

如果有帮助,我知道 Swift 并且该应用程序是 iOS。谢谢!!

更新 #2

所以我选择尝试获取所有用户的快照并完全绕过“管理”节点。代码如下:

const db = admin.database();
const ref = db.ref('users');

return ref.once('value').then((adminSnap) => {

    console.log('admin key:', adminSnap.key)

    // create blank array to store 
    let newUserCount = 0;

    // iterate over adminSnap to get each individual snap
    adminSnap.forEach(function (userSnap) {

        const userData = userSnap.val();
        const userKey = userSnap.key

        // console.log('email?', userData.email, 'user key:', userKey, 'new user?', userData.newUser)

        if (userData.newUser === true) {
            newUserCount++
            console.log('new user:', userKey, userData.newUser, userData.email)
        }
    });

    console.log(newUserCount)
})

这个新代码有效,并在我执行推送通知时为我的徽章参数提供了编号,但我想知道它是否是最有效的做事方式。另外,随着我​​的数据库越来越大,它不会对服务器征税/减慢速度吗?我的 Firebase 帐户不会占用大量带宽吗?

我认为这将是一件简单的事情,但它变得有点麻烦。我愿意以不同的方式来完成这项工作。谢谢!

【问题讨论】:

    标签: javascript typescript google-cloud-functions


    【解决方案1】:

    经过更多研究,我最终放弃了我原来的方法。我决定用新的用户数在我的 Firebase 数据库上创建一个新节点,然后通过其他地方的代码更新它。这是最简单的方法,并且会使用最少的带宽。

    这是我的最终代码:

    function sendAlertToiPhone() {
    
    console.log('test E')
    
    // Get a database reference
    const db = admin.database();
    const ref = db.ref('stats');
    
    ref.child('newUserCount').once('value').then((snapshot) => {
    
        const newUserCount = snapshot.val()
    
        console.log('new user count:', newUserCount)
    
        // send to Phontaine's iPhone 6
        const FCMToken = "blahbehtyblahblah"
    
        const payload = {
            notification: {
                title: 'New User',
                body: 'Moneypants has a new download.',
                sound: 'default',
                badge: String(newUserCount)
            }
        };
    
        return admin.messaging().sendToDevice(FCMToken, payload)
            .then(function (response) {
                console.log("Successfully sent message:", response);
            })
            .catch(function (error) {
                console.log("Error sending message:", error);
            });
    
    }).catch(function (err) {
        console.log('new user count error:', err);
    })
    }
    

    【讨论】: