LoginSignup
25
17

More than 3 years have passed since last update.

ExpoのPush Notificationsを使う

Last updated at Posted at 2018-11-16

更新(2019年9月22日)

2019年9月22日現在、expoでPermissionを呼び出す方法が変更されているようです。
末尾に新規コードを載せておきます。

(以下はでは動きません)。

手順

  • Tokenを取得する(これがしんどかった)
  • Tokenを使ってpushを送る

ハマったこと

Tokenの取得に際し、ずっと下記のようなエラーに悩まされた。
promiseうんぬんはawaitにtry{}catchを入ればよい。が、後者は???という感じ。実機にてExpoアプリを削除し、再度「許可」することで復活した。エミュレータで許可しないように注意。

[Unhandled promise rejection: Error: The Expo push notification service is supported only for Expo projects. Ensure you are logged in to your Expo developer account on the computer from which you are loading your project.]

Tokenの取得

本家サイト含め、ネット上のサンプルコードが動かない。2018年11月10日時点で、下記のコードで取得できた。

App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Permissions, Notifications } from 'expo';

//取得のためのコード
async function registerForPushNotificationsAsync() {

  //warningがでるのを防ぐためにtry catchを入れる
  try {

    const { status: existingStatus } = await Permissions.getAsync(
      Permissions.NOTIFICATIONS
    );
    let finalStatus = existingStatus;

    if (existingStatus !== 'granted') {
      const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
      finalStatus = status;
    }

    if (finalStatus !== 'granted') {
      return;
    }

    let token = await Notifications.getExpoPushTokenAsync();

    //コンソールに出力
    console.log(token);

  } catch (error) {
    console.log(error);
  }
}


export default class App extends React.Component {
  componentDidMount() {
    //呼び出し
    registerForPushNotificationsAsync();
  }
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Open up App.js to start working on your app!</Text>
      </View>
    );
  }
}

下記のようなTokenが表示される(はず)。

[16:54:07] ExponentPushToken[gicUyxNQ23PxCexxxxxxxx]

Tokenが取得できればpushのテストが下記サイトで可能。

PHPから送る

ここにやり方が書いてある。

index.php
<?php

require_once __DIR__.'/vendor/autoload.php';


// インスタンス作成
$expo = \ExponentPhpSDK\Expo::normalSetup();

// 設定
$expo->subscribe(
    'unique_identifier',
    'ExponentPushToken[gicUyxNQ23PxCexxxxxxxx]'
);

// 電文作成
$notification = ['body' => 'Hello World!', 'data' => '{"name":"hoge", "age":"33"}'];

// 送信
$expo->notify('unique_identifier', $notification);

詳細は本家サイトを見る。

受け取ったデータの処理

フォワグラウンド(アプリ起動中)は通知がでないので、アプリで表示等の処理をする必要があります。

index.php
import React from 'react';
import { StyleSheet, Text, View, Alert } from 'react-native';
import { Permissions, Notifications } from 'expo';


export default class App extends React.Component {
  componentDidMount() {

    //リスナー登録
    this._notificationSubscription = Notifications.addListener(this._handleNotification);

    //badge消したり
    Notifications.getBadgeNumberAsync().then(badgeNumber => {
      if(badgeNumber !==0){
        Notifications.setBadgeNumberAsync(badgeNumber - 1);
      }
    })

  }

  _handleNotification = (notification) => {
    if(notification.origin === 'selected'){
      //バックグラウンドで通知
    }else if(notification.origin === 'received'){
      //フォアグラウンドで通知
      Alert.alert('通知が来ました:' + notification.data.name);
      console.log(notification.data.name);
    }
  }

  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Open up App.js to start working on your app!</Text>
      </View>
    );
  }
}

参考サイト

更新:サンプル(2019年9月22日)

App.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { Notifications } from 'expo';
import  * as Permissions from 'expo-permissions'; //呼び出し方変わってる

export default class App extends React.Component {

    registerForPushNotificationsAsync = async () => {

        try {
            //現在のNotificationパーミッション状況取得
            const { status: existingStatus } = await Permissions.getAsync(
                Permissions.NOTIFICATIONS
            );
            let finalStatus = existingStatus;

            //statusが許可じゃなければ(許可済みなら何もしない)
            if (existingStatus !== 'granted') {
                //許可を尋ねる
                const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
                finalStatus = status;
            }

            //それでも許可されてなかったら何もしない
            if (finalStatus !== 'granted') {
                return;
            }

            const token = await Notifications.getExpoPushTokenAsync();

            alert("token=" + token);
            console.log(token);
        } catch (e) {
            console.log(e);
        }
    }


    render() {
        return (
            <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                <Text>App</Text>
                <Button
                    title="get Notification token"
                    onPress={this.registerForPushNotificationsAsync}
                />
            </View>
        );
    }
}
25
17
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
25
17