前回つくった、Expoアプリにプッシュ通知を送るローカルサーバ。
すんなりうまくいったので、これをそのままHerokuやら、Lambdaやら、Cloud Functionsやらにデプロイすれば、問題なくプッシュ通知を遅れると思い込んでいましたが、冷静に考えると、Expoにログインしないと400が返ってくるため、このままでは動かないことは火を見るよりも明らかでした。
どうしたものかと、Expoにログインする方法を調べてみたところ、expo-server-sdk たるものを使うのがセオリーのようです。
ソースコード
const { Expo } = require('expo-server-sdk'); let expo = new Expo({ accessToken: process.env.EXPO_ACCESS_TOKEN }); const tokens = [ 'ExponentPushToken[XXXXXX]', 'ExponentPushToken[XXXXXX]' ]; const messages = []; tokens.forEach((token) => { messages.push({ to: token, sound: 'default', title: '本気で Push! Push!', badge: 0 | Math.random() * 9 + 1, body: 'We can say!', data: { timestamp: Date.now() } }) }); const chunks = expo.chunkPushNotifications(messages); const tickets = []; for (let chunk of chunks) { try { let ticketChunk = await expo.sendPushNotificationsAsync(chunk); tickets.push(...ticketChunk); } catch (error) { console.error(error); } } const receiptIds = []; for (let ticket of tickets) { if (ticket.id) { receiptIds.push(ticket.id); } } const receiptIdChunks = expo.chunkPushNotificationReceiptIds(receiptIds); for (let chunk of receiptIdChunks) { try { let receipts = await expo.getPushNotificationReceiptsAsync(chunk); for (let receiptId in receipts) { let { status, message, details } = receipts[receiptId]; if (status === 'ok') { continue; } else if (status === 'error') { if (details && details.error) { console.error(message); } } } } catch (error) { console.error(error); } }
ローカルサーバ用のコード をまるまる移植するとしたらこんな感じです。
あとはこれをHerokuやら、Lambdaやらにデプロイすれば動くはずですが、実際に運用する際はtokensをデータベースから取得するはずなので、とりあえず、Cloud FunctionsにでデプロイしてCloud Firestoreからトークンを取得する方向で実装を試みようと思います。