android - 在特定条件下触发通知在 Firebase 上满足

标签 android firebase firebase-realtime-database google-cloud-functions

您好,我想向那些将商品添加到购物车但未在 7 天内购买的用户触发通知。

我想自动完成。在 firebase 上实现它的正确方法是什么?

最佳答案

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

// timestamp the cart with last item added date/time
exports.timestampCartItem =
  functions.database.ref('/users/{uid}/cart/{item}')
    .onCreate((snapshot, context) => {
      return snapshot.ref.parent('timestamp').set((new Date()).getTime()); // milliseconds
    })



// Call this function every hour using https://cron-job.org/en/
const CART_EXPIRE_TIME = Number(7 * 24 * 60 * 60 * 1000); // days * hours * minutes * seconds * milliseconds
exports.scanZombieCarts = functions.https.onRequest((request, response) => {

  const server_time = Number((new Date()).getTime());
  const usersDBRef = admin.database().ref('users');
  const notifyDBRef = admin.database().ref('notify'); // queue to send notifications with FCM

  return usersDBRef.once('value')
    .then(users => {
      let zombie_promises = [];
      users.forEach(usersnap => {
        let userid = usersnap.key;
        let user = usersnap.val();
        if (user.hasOwnProperty('cart')) {
          let cart_timestamp = Number(user.cart.timestamp || 0) + CART_EXPIRE_TIME;
          if (cart_timestamp < server_time) {
            zombie_promises.push(
              notifyDBRef.push({
                'notification': {
                  'body': `You have ${Object.keys(user.cart).length} items in your Cart.`,
                  'title': 'Sales end soon!'
                },
                'token': user.devicetoken
              })
            );
          }
        }
      })

      return Promise.all(zombie_promises);
    })
    .then(() => {
      let elapsed_time = ((new Date()).getTime() - (server_time)) / 1000;
      response.status(200);
      response.send(`<h2>Finished scan of Zombie Carts...${elapsed_time} seconds</h2>`);
      return null;
    })
    .catch(err => {
      response.status(500);
      response.send(`<h2>Scan failed</h2>`);
      console.log(err);
    })
});

// IMPORTANT:
// https://console.developers.google.com/apis search for and enable FCM
exports.sendReminder =
  functions.database.ref('/notify/{message}')
    .onCreate((snapshot, context) => {
      let message = snapshot.val();

      let send_and_consume = [
        admin.messaging().send(message), // send message to device
        snapshot.ref.remove()            // consumes message from queue
      ]

      return Promise.all(send_and_consume)
        .catch(err => {
          console.log(err); // probably bad token
        })
    })

注意事项 这假定当用户打开应用程序时,该应用程序使用从消息获取的设备 token 写入“users/{uid}/devicetoken” key 。

请参阅有关启用 FCM 和 CRON 触发器的内部评论。

测试 将所有这些添加到您的 index.js 文件中,使用 firebase deploy 上传到服务器。

在控制台中手动编辑 Firebase 数据库以观察触发器自动添加/更新时间戳。

使用 firebase serve --only functions 从您的机器本地测试/调试您的 https 触发器。它会给你一个本地主机链接来运行,你可以在控制台中捕获错误。

关于android - 在特定条件下触发通知在 Firebase 上满足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51383967/

相关文章:

swift - Snapshot.value 在 setValueForKeys 上崩溃

android - Firebase 与 Realm。反序列化 POJO 类

android - SQLite 本地数据库与 Firestore 使用字符串转换器

ios - 对来自 firebase 的 tableView 数据进行排序

javascript - 监听 Firebase React Native 的变化

android - 如何通过windows命令行查看模拟器上安装的apks?

android - 在我的 Windows 7 机器上安装 Android 平台 2.1 时出现问题

javascript - 有没有办法让 Web 应用程序在关闭时继续运行?

android - Flutter:构建 APK 时如何传递 Gradle 参数?

android - 无法使评级栏与 TextView 对齐