💓

Expo × Firebase FCMベース実装

2025/01/13に公開

はじめに

現在の業務で、ExpoとFirebase FCMの実装をしていたので、その実装方法についてまとめました。
ハンズオンなので、各単語に関しての説明は省略させていただきます。余裕があれば追記していきたいと思います。

設定

FCMの設定をする際に必要な手順は下記の内容です。

  • IdentifiersのAPNsを設定
  • APNs認証キーを設定
  • xcodeのプロビジョニングファイルを設定
  • FCMで送信できたか確認

一つづつ説明していきます。

IdentifiersのAPNsのON

Identifiersページから自分が使うIdentifiersを選択し、下記画像のページを開きます。

Push Notificationにチェックが入っているか確認してください。入っていなければいれ、証明書がなければ発行していれてください。

証明書の発行方法

macのlunchpadにある検索欄にキーチェーンアクセスと入力して、アプリを押下します。

画面上部にある、キーチェーンアクセスから、証明書アシスタント→証明局に証明書を要求を押下します。

自分のメールアドレスを入力し、ディスクに保存を選択し、続けるを押下します。

証明書が発行されます。

再度、Identifiersページから自分が使うIdentifiersを選択し、Push Notificationを選択し、下記のページを開きます。
ファイルを選択で、先ほど発行した証明書を入れ、続くボタンを押下します。

これでAPNsをONにすることができました🎉

firebase consoleの設定でcloud messageを開いて、APNs認証キーを設定

Apple developerのkeysを開いて、自分のkeyを選択してください。選択すると、下記の画像のようなページが表示されると思います。

そこで、APNsのチェックを入れてRegisterボタンを押下してください。
キーIDが表示されたら保存してください。後で使用します。

firebase consoleにある歯車アイコンのプロジェクトの設定を押下します。

Cloud Messageingのタブを開き、下にあるAppleアプリの構成までスクロールします。

APNs認証キーを押下し、先ほど発行したAPNsのkeyをアップロードします。先ほど表示されたキーIDとチームIDが必要になるのでコピーしてきます。

チームIDの取得方法

チームIDは、Apple Developerの右上の一番上にある自分の所属している組織名をクリックし

遷移した画面を少しスクロールするとメンバーシップの詳細というのがあるので、チームIDをコピーしてください。

xcodeのプロビジョニングファイルを設定

私のPJは、managed workflowで行っていますが、prebuildを行って、一時的にiosファイルを作成しXcodeの内容を編集します。後でVSCode上に生成されたファイルを消せば問題ありません。

下記コマンドを実行します。

$ npx expo prebuild

XcodeのOpen ~~ を開き、対象のPJにあるiosファイルを開いて、~~.xcodeprojファイルを選択してください。

これで、PJを開くことができるので、左上の対象のPJ名が書いてあるところを押下し、Setting & Capabilitiesを選択します。
Automatically manage signingのチェックをはずして、Provisioning ProfileでDownload Profileを選択します。

Provisioning Profileを選択する画面が出てきたら、先ほど作成したAd Hoc配布用のProvisioning Profileを選択してSelect Profileを押下します。

そうすると、Provisioning Profileがダウンロードされ、設定されます🎉

https://softmoco.com/devenv/how-to-set-ios-provisioning-profile-in-xcode.php

FCMの実装

Expoリポジトリのルートにサンプルとして下記の実装を書きました。

app.config.tsにも、公式ドキュメントに従って実装するコードがあるので、こちらをご覧ください。
https://rnfirebase.io/messaging/usage

index.tsx
import messaging from '@react-native-firebase/messaging'

// 通知のリクエスト許可
async function requestUserPermission() {
  const authStatus = await messaging().requestPermission()
  const enabled =
    authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL

  if (enabled) {
    console.log('Authorization status:', authStatus)
  }
}

export default function Page() {
  const [fcmToken, setFcmToken] = useState<string | null>(null)

  // トークンの取得
  async function getFcmToken() {
    const token = await messaging().getToken()
    if (token) {
      console.log('FCM Token:', token)
      setFcmToken(token)
    } else {
      console.log('Failed to get FCM token.')
    }
  }

  // トークンのコピー
  const copyToClipboard = () => {
    if (fcmToken) {
      Clipboard.setStringAsync(fcmToken).catch(error => {
        console.error(error)
      })
      Alert.alert('トークンをコピーしました!')
    } else {
      Alert.alert('コピーするトークンがありません。')
    }
  }

  useEffect(() => {
    // 通知許可のリクエスト
    requestUserPermission()
      .then(result => {
        console.log(result)
      })
      .catch(error => {
        console.log(error)
      })

    // FCMトークンの取得
    getFcmToken()
      .then(result => {
        console.log(result)
      })
      .catch(error => {
        console.log(error)
      })
  }, [])

return (
    <ScrollView>
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <SafeAreaView style={styles.container}>
            <View style={styles.container}>
              <Text>FCM Token</Text>
              {fcmToken ? <Text>{fcmToken}</Text> : <Text>トークンを取得中...</Text>}
              <Button
                text="トークンを再取得"
                onClick={() => {
                  getFcmToken()
                    .then(result => {
                      console.log(result)
                    })
                    .catch(error => {
                      console.log(error)
                    })
                }}
              />
              <Button text="トークンをコピー" onClick={copyToClipboard} />
          </View>
        </SafeAreaView>
      </TouchableWithoutFeedback>
    </ScrollView>
  )

このように、デバイスに表示されたトークンをコピーします。
コピーしたトークンは、FCMのテスト送信で使用します。

FCMを送信

firebase consoleのCloud Messageingを開きます。
その画面の新しいキャンペーンボタンを押下し、通知を選択して下記の画面を表示させます。

テストメッセージを送信ボタンを押下し、下記の画面を表示させ、先ほど取得したデバイストークンを入れます。

入力したデバイストークンにチェックを入れ、テストボタンを押下すると、デバイスに通知が行きます。

端末にプッシュ通知

このように、デバイスにプッシュ通知が届くと思います。

Androidはフォアグラウンドにしていると、通知が届かないので、フォアグラウンドでも通知がいくように実装しました。下記に記事を書いたので、ご覧ください。
https://zenn.dev/yumemi9808/articles/c85c59ca750793

Discussion