如何使用Typescript查询Firebase?

时间:2019-01-01 10:44:39

标签: javascript typescript google-cloud-functions

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

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

我正在使用Firebase函数和Typescript(带有VSCode)。我的行动方针是:

  1. 从“管理”节点获取用户ID列表
  2. 遍历“用户”节点上的那些用户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),然后在发送推送通知(我在上面的步骤4)时获取'badge'参数的新用户数量?

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

有什么想法吗?我已经待了好几天了。

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

更新#2

因此,我选择尝试获取所有用户的快照,并完全绕开“ admin”节点。这是代码:

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)
})

此新代码有效,并为我提供了执行推送通知时的badge参数编号,但是我想知道这是否是最有效的处理方式。另外,随着我​​的数据库规模的扩大,它不会增加服务器的负担/降低速度吗?而且我的Firebase帐户不会花很多带宽吗?

我认为这将是一件简单的事情,但这变得有些麻烦。我愿意以另一种方式来完成此任务。谢谢!

1 个答案:

答案 0 :(得分:0)

经过更多研究,我最终放弃了原来的方法。我决定只在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);
})
}