您好,我想向那些将商品添加到购物车并且在7天内没有购买的用户触发通知。
我想自动做。在firebase上实现此功能的正确方法是什么?
答案 0 :(得分:2)
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
})
})
注释 假设用户打开应用程序时,该应用程序会使用从Messages获取的设备令牌编写一个'users / {uid} / devicetoken'键。
请参阅有关启用FCM和CRON触发器的内部注释。
测试
将所有这些添加到您的index.js文件中,使用firebase deploy
上载到服务器。
在控制台中手动编辑Firebase数据库,以查看触发器自动添加/更新时间戳。
使用firebase serve --only functions
从您的计算机本地测试/调试https触发器。它将为您提供一个本地主机链接来运行,并且您可以在控制台中捕获错误。
答案 1 :(得分:0)
不幸的是,现在FCM中没有类似的东西,但是您可以使用AlarmManager在自己的服务器或应用程序中实现计划推送,如下所示: 在你的清单上
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
在您看来
Calendar sevendayalarm = Calendar.getInstance();
sevendayalarm.add(Calendar.DATE, 7);
Intent intent = new Intent(this, AlarmReciever.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 001, intent, 0);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, sevendayalarm.getTimeInMillis(), pendingIntent);
您的警报接收者
public class AlarmReciever extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// push notification
}
}
别忘了在清单中声明收货人
<receiver android:name=".AlarmReceiver" >
<intent-filter>
<action android:name="NOTIFICATION_SERVICE" />
</intent-filter>
</receiver>