在firebase实时数据库中添加新节点时,使用云功能发送推送通知?

时间:2018-05-29 09:32:55

标签: firebase firebase-cloud-messaging google-cloud-functions

在消息节点

中添加子项时发送通知

每当在Message节点中添加新子节点时,所有用户都应该收到“你有新消息”这样的消息。我对node.js知之甚少,所以我想要发送通知的云功能。

1 个答案:

答案 0 :(得分:2)

您将在下文中找到涵盖您需求的教程或代码示例的链接。 (更新:我还复制了第一个示例的完整代码,这是官方的Firebase示例)。

https://firebase.google.com/docs/functions/use-cases#notify_users_when_something_interesting_happens

https://github.com/firebase/functions-samples/blob/master/developer-motivator/functions/index.js

https://android.jlelse.eu/serverless-notifications-with-cloud-functions-for-firebase-685d7c327cd4

更新:在评论之后,我会粘贴第一个示例(这是官方的Firebase示例)中的源代码。

  

使用Firebase管理SDK完成发送通知。网络   客户端将单个设备令牌写入实时数据库   函数用于发送通知。

     

依赖项列在functions / package.json中。

示例数据库结构

  

用户登录该应用并被要求启用通知   他们的浏览器如果他们成功启用了设备通知   令牌保存在数据存储区下   /用户/ $ UID / notificationTokens:

/functions-project-12345
    /users
        /Uid-12345
            displayName: "Bob Dole"
            /notificationTokens
                1234567890: true
            photoURL: "https://lh3.googleusercontent.com/..."
  

如果用户开始关注我们将写入的其他用户   /跟踪/ $ followedUid / $ followerUid:

/functions-project-12345
    /followers
        /followedUid-12345
            followerUid-67890: true
    /users
        /Uid-12345
            displayName: "Bob Dole"
            /notificationTokens
                1234567890: true
            photoURL: "https://lh3.googleusercontent.com/..."

触发规则

  

每次跟随标志的值发生变化时,该函数都会触发   /跟踪/ $ followedUid / $ followerUid。

<强> Index.js

/**
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

/**
 * Triggers when a user gets a new follower and sends a notification.
 *
 * Followers add a flag to `/followers/{followedUid}/{followerUid}`.
 * Users save their device notification tokens to `/users/{followedUid}/notificationTokens/{notificationToken}`.
 */
exports.sendFollowerNotification = functions.database.ref('/followers/{followedUid}/{followerUid}')
    .onWrite((change, context) => {
      const followerUid = context.params.followerUid;
      const followedUid = context.params.followedUid;
      // If un-follow we exit the function.
      if (!change.after.val()) {
        return console.log('User ', followerUid, 'un-followed user', followedUid);
      }
      console.log('We have a new follower UID:', followerUid, 'for user:', followerUid);

      // Get the list of device notification tokens.
      const getDeviceTokensPromise = admin.database()
          .ref(`/users/${followedUid}/notificationTokens`).once('value');

      // Get the follower profile.
      const getFollowerProfilePromise = admin.auth().getUser(followerUid);

      // The snapshot to the user's tokens.
      let tokensSnapshot;

      // The array containing all the user's tokens.
      let tokens;

      return Promise.all([getDeviceTokensPromise, getFollowerProfilePromise]).then(results => {
        tokensSnapshot = results[0];
        const follower = results[1];

        // Check if there are any device tokens.
        if (!tokensSnapshot.hasChildren()) {
          return console.log('There are no notification tokens to send to.');
        }
        console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.');
        console.log('Fetched follower profile', follower);

        // Notification details.
        const payload = {
          notification: {
            title: 'You have a new follower!',
            body: `${follower.displayName} is now following you.`,
            icon: follower.photoURL
          }
        };

        // Listing all tokens as an array.
        tokens = Object.keys(tokensSnapshot.val());
        // Send notifications to all tokens.
        return admin.messaging().sendToDevice(tokens, payload);
      }).then((response) => {
        // For each message check if there was an error.
        const tokensToRemove = [];
        response.results.forEach((result, index) => {
          const error = result.error;
          if (error) {
            console.error('Failure sending notification to', tokens[index], error);
            // Cleanup the tokens who are not registered anymore.
            if (error.code === 'messaging/invalid-registration-token' ||
                error.code === 'messaging/registration-token-not-registered') {
              tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
            }
          }
        });
        return Promise.all(tokensToRemove);
      });
});

<强>的package.json

{
  "name": "fcm-notifications-functions",
  "description": "Send FCM notifications Firebase Functions sample",
  "dependencies": {
    "firebase-admin": "~5.11.0",
    "firebase-functions": "^1.0.0"
  },
  "devDependencies": {
    "eslint": "^4.13.1",
    "eslint-plugin-promise": "^3.6.0"
  },
  "scripts": {
    "lint": "./node_modules/.bin/eslint --max-warnings=0 .",
    "serve": "firebase serve --only functions",
    "shell": "firebase experimental:functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "private": true
}