Help us understand the problem. What is going on with this article?

ExpoのPush Notificationsを使う

更新(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>
        );
    }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした