LoginSignup
0
0

More than 1 year has passed since last update.

【React Native】Cloud Functions側の処理 expo-server-sdkとFirebaseで通知機能を実装!

Posted at

expo-server-sdk

expoPushTokenを使ってクライアント側に通知を送ることができます。

firebase-functions

クラウドサービスの構築と接続に使用するサーバーレスのランタイム環境です。
シンプルで一義的な関数を作成できます。関数の定期実行が可能です。

Cloud Firestoreに保存されているデータを読み取り通知

今回は1時間毎に通知を送る仕様で作成します。データ構造は以下のとおりです。
シンプルにするためコレクション名を時間に、ドキュメント内のデータはexpoPushTokenbodyの2つとしています。
スクリーンショット 2023-01-03 20.42 1.png
※クライアント側のexpoPushTokenの取得方法や設定は以下のリンクをご参照ください。

Cloud Functions

かたまりの意味を持つchunksに通知の情報をまとめます。
その後、expo.sendPushNotificationsAsync()により通知を行います。

    let chunks = expo.chunkPushNotifications(messages)

    ;(async () => {
      for (let chunk of chunks) {
        try {
          await expo.sendPushNotificationsAsync(chunk)
        } catch (error) {
          ...
        }
      }
    })()
  })

全体のコードです。

index.ts
import * as functions from "firebase-functions"
import * as admin from "firebase-admin"
import { Expo, ExpoPushMessage } from "expo-server-sdk"

admin.initializeApp()

interface DATA {
  expoPushToken: string
  body: string
}

exports.scheduledFunctionPushNotifications = functions
// 場所
  .region("asia-northeast1")
// 頻度:毎時0分  左から「分、時、日、月、曜日」
  .pubsub.schedule("0 * * * *")
// タイムゾーン
  .timeZone("Asia/Tokyo")
// 主処理
  .onRun(async () => {
    let expo = new Expo()
    // 現在の日本時間を取得
    const japanStandardTime = new Date().toLocaleString("ja-JP", {
      timeZone: "Asia/Tokyo",
    })
    const nowHour = new Date(japanStandardTime).getHours().toString()

    // 現在の時間と一致する時間名のコレクション内の全データを取得
    const snapshot = await admin.firestore().collection(nowHour).get()
    const firestoreDatas = snapshot.docs.map((doc) => doc.data() as DATA)
    
    // 通知情報を保存する配列を作成
    let messages: ExpoPushMessage[] = []

    // コレクション内のデータをfirestoreDataとして一つずつ取得
    for (let firestoreData of firestoreDatas) {
      let pushToken = firestoreData.expoPushToken
      let body = firestoreData.body
    // ExpoPushTokenの有効性を確認する
      if (!Expo.isExpoPushToken(pushToken)) {
        console.error(`Push token ${pushToken} is not a valid Expo push token`)
        continue
      }
    
    // 一人ひとりの通知情報を保存用の配列に格納
      messages.push({
        to: pushToken,
        sound: "default",
        body,
      })
    }

    // 通知
    let chunks = expo.chunkPushNotifications(messages)
    let tickets = []

    ;(async () => {
      for (let chunk of chunks) {
        try {
          let ticketChunk = await expo.sendPushNotificationsAsync(chunk)
          console.log(ticketChunk)
          tickets.push(...ticketChunk)
        } catch (error) {
          console.error(error)
        }
      }
    })()
  })

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0