3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

さくらインターネットAdvent Calendar 2016

Day 9

さくらのVPSにParse Serverを構築してスマホにプッシュ通知してみる。

Last updated at Posted at 2016-12-08

OSSでmBaaSを構築できるParse Serverをいつも使っているさくらのVPSに構築し、
Android端末にプッシュ通知をしてみたいと思います。
※今回は動かすことを目的としているので、必要最低限の設定操作のみ行います。

Parse Serverとmongodbの構築

今回は、さくらのVPSにParse Serverとmongodbを構築します。

Parse Server

# yum install epel-release -y
# yum install gcc gcc-c++ git -y
# yum install nodejs npm --enablerepo=epel -y
# git clone git://github.com/creationix/nvm.git ~/.nvm

~/.bash_profileに、以下3行を追加します。

# vi ~/.bash_profile
if [[ -s ~/.nvm/nvm.sh ]];
 then source ~/.nvm/nvm.sh
fi
# source ~/.nvm/nvm.sh
# nvm install v4.3.0
# nvm alias default v4.3.0

※次のコマンドを実行すると、Parse Serverのセットアップが始まりますが

# sh <(curl -fsSL https://raw.githubusercontent.com/parseplatform/parse-server/master/bootstrap.sh)

このような、エラーが途中発生するため

../node_modules/nan/nan.h:43:3: error: #error This version of node/NAN/v8 requires a C++11 compiler

gcc、g++のバージョンアップをします。(バージョンアップをしなくとも、Parse Serverは動作しますが念のため)

※バージョンアップ前

# gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
コンフィグオプション: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
スレッドモデル: posix
gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)

# g++ -v
Using built-in specs.
Target: x86_64-redhat-linux
コンフィグオプション: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
スレッドモデル: posix
gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)

※バージョンアップ後

# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-2/root/usr/libexec/gcc/x86_64-redhat-linux/4.8.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/opt/rh/devtoolset-2/root/usr --mandir=/opt/rh/devtoolset-2/root/usr/share/man --infodir=/opt/rh/devtoolset-2/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,fortran,lto --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --disable-libgcj --with-isl=/dev/shm/home/centos/rpm/BUILD/gcc-4.8.2-20140120/obj-x86_64-redhat-linux/isl-install --with-cloog=/dev/shm/home/centos/rpm/BUILD/gcc-4.8.2-20140120/obj-x86_64-redhat-linux/cloog-install --with-mpc=/dev/shm/home/centos/rpm/BUILD/gcc-4.8.2-20140120/obj-x86_64-redhat-linux/mpc-install --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.2 20140120 (Red Hat 4.8.2-15) (GCC)

# g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-2/root/usr/libexec/gcc/x86_64-redhat-linux/4.8.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/opt/rh/devtoolset-2/root/usr --mandir=/opt/rh/devtoolset-2/root/usr/share/man --infodir=/opt/rh/devtoolset-2/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,fortran,lto --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --disable-libgcj --with-isl=/dev/shm/home/centos/rpm/BUILD/gcc-4.8.2-20140120/obj-x86_64-redhat-linux/isl-install --with-cloog=/dev/shm/home/centos/rpm/BUILD/gcc-4.8.2-20140120/obj-x86_64-redhat-linux/cloog-install --with-mpc=/dev/shm/home/centos/rpm/BUILD/gcc-4.8.2-20140120/obj-x86_64-redhat-linux/mpc-install --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.2 20140120 (Red Hat 4.8.2-15) (GCC)

giwaさんとzoepontaさんの記事を参考にさせていただきました。

http://qiita.com/giwa/items/28c754d8fc2936c0f6d2
http://qiita.com/zoeponta/items/a2e109304729ffa23d81

# sh <(curl -fsSL https://raw.githubusercontent.com/parseplatform/parse-server/master/bootstrap.sh)

             `.-://////:-..`
         `:/oooooooooooooooo+:.`
      `:+oooooooooooooooooooooo+/`
     :+ooooooooooooooooooooooooooo/.
   .+oooooooooooooo/:.....-:+ooooooo-
  .+ooooooooooooo/` .:///:-` -+oooooo:
 `+ooooooooooooo: `/ooooooo+- `ooooooo-
 :oooooooooooooo  :ooooooooo+` /oooooo+
 +ooooooooooooo/  +ooooooooo+  /ooooooo.
 oooooooooooooo+  ooooooooo`  .oooooooo.
 +ooooooooooo+/: `ooooooo`  .:ooooooooo.
 :ooooooo+.`````````````  /+oooooooooo+
 `+oooooo- `ooo+ /oooooooooooooooooooo-
  .+ooooo/  :/:` -ooooooooooooooooooo:
   .+ooooo+:-..-/ooooooooooooooooooo-
     :+ooooooooooooooooooooooooooo/.
      `:+oooooooooooooooooooooo+/`
         `:/oooooooooooooooo+:.`
             `.-://////:-..`
              parse-server

Enter an installation directory
(/root): <エンターを押下>
This will setup parse-server in /root
Do you want to continue? (Y/n): <Yを入力>
\033[0;32m\xE2\x9C\x93\033[0m node: v4.3.0
\033[0;32m\xE2\x9C\x93\033[0m npm: 2.14.12
Setting up parse-server in /root\n{CHECK} /root exists
Enter your Application Name: <SampleApplicationと入力>
Enter your Application Id (leave empty to generate): <エンターを押下>
****************************************
Enter your Master Key (leave empty to generate): <エンターを押下>
****************************************
Enter your mongodbURI (mongodb://127.0.0.1:27017/parse): <エンターを押下>
 
...インストールのログが流れます。

Test your setup with:\n\ncurl -X POST -H 'X-Parse-Application-Id: ****************************************' \ -H 'Content-Type: application/json' \ -d '{"foo":"bar"}' http://localhost:1337/parse/classes/TestObject\n

生成される、 Application IdMaster Key は使用するのでメモしてください。

mongodb

# npm install -g mongodb-runner
# mongodb-runner start

ParseServerを起動

# npm start

動作確認

# curl -X POST -H 'X-Parse-Application-Id: <Application Id>' \
             -H 'Content-Type: application/json' \
             -d '{"foo":"bar"}' http://localhost:1337/parse/classes/TestObject
 {"objectId":"yarJrnz15B","createdAt":"2016-12-07T02:21:52.563Z"}

{"objectId":"ランダム値","createdAt":"作成日時"} のレスポンスがあれば正常に起動しています。

FCMの設定

FireBaseConsole上から、Notificationsの設定を行い必要な情報を取得します。(詳しい手順は省略します)
パッケージ名が必要になるので、事前に実装するアプリケーションをCreate New Projectしておいてください。

※アプリレベルのbuild.grableのapplicationIdを入力してください。
1.png

※この場所にある値を入力。
3.png

コンソールにスキップをクリック。
2.png

プロジェクトの設定 → クラウド メッセージングに
GCM sender ID または 送信者ID
Server key (legacy token) または サーバーキー
が表示されます、取得できたらメモしてください。

ParseServer設定ファイルの編集

FCMで取得した情報をParse Serverの設定ファイルに追加します。
先ほど起動したParse Serverを一旦停止します。

# <Control + cでParseServerを停止>

※編集前

# cat config.json
{
  "appId": "****************************************",
  "masterKey": "****************************************",
  "appName": "SampleApplication",
  "cloud": "./cloud/main",
  "databaseURI": "mongodb://127.0.0.1:27017/parse"
}

※編集後

# vi config.json
 
{
    "appId": "<そのまま>",
    "masterKey": "<そのまま>",
    "appName": "<そのまま>",
    "cloud": "<そのまま>",
    "databaseURI": "<そのまま>", ←カンマを追加!
    "push": {
        "android": {
            "senderId": "<GCM sender ID または 送信者ID>",
            "apiKey": "<Server key (legacy token) または サーバーキー>"
        }
    }
}

Parse Serverを再び起動します。

# npm start

アプリの実装

Parse SDK for Android

以下をbuild.gradle (Module:app)に追加
compile 'com.parse:parse-android:1.13.1'

CustomReceiver.java (新規作成)

そのままコピー&ペーストしてください。

import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
 
import com.parse.ParsePushBroadcastReceiver;
 
import org.json.JSONException;
import org.json.JSONObject;
 
import static android.content.Context.NOTIFICATION_SERVICE;
 
public class CustomReceiver extends ParsePushBroadcastReceiver {
 
    @Override
    public void onReceive(Context context, Intent intent) {
        JSONObject json = null;
 
        try {
            json = new JSONObject(intent.getStringExtra("com.parse.Data"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
 
        Notification.Builder builder = new Notification.Builder(context);
 
        if (json != null) {
            try {
                builder.setContentTitle(json.getString("title"));
                builder.setContentText(json.getString("body"));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            return;
        }
 
        builder.setDefaults(Notification.DEFAULT_ALL);
        builder.setSmallIcon(R.mipmap.ic_launcher);
 
        Notification notification = builder.build();
 
        NotificationManager notificationManager;
        notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
 
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(1, notification);
    }
}

ParseApplication.java (新規作成)

以下の2つの部分を書き換えます。

"<Application Id>"
"http://<IPアドレス>:1337/parse"

import android.app.Application;
 
import com.parse.Parse;
import com.parse.ParseInstallation;
 
public class ParseApplication extends Application{
 
    @Override
    public void onCreate() {
        super.onCreate();
        Parse.initialize(new Parse.Configuration.Builder(getApplicationContext())
                .clientKey(null)
                .applicationId("<Application Id>")
                .server("http://<IPアドレス>:1337/parse")
                .build()
        );
        ParseInstallation.getCurrentInstallation().saveInBackground();
    }
}

AndroidManifest.xml

YOUR_PACKAGE_NAME の部分にパッケージ名。
YOUR_SENDER_ID の部分に取得した Server key (legacy token) または サーバーキー を入力。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="YOUR_PACKAGE_NAME">

    <!--    追加行 START -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <!--    パッケージ名をする必要があります  -->
    <uses-permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" />
    <!--    パッケージ名を変更する必要があります  -->
    <permission android:protectionLevel="signature"
        android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" />
    <!--    追加行 END -->

    <!--    applicationタグの属性にandroid:name=".ParseApplication"を追加しています    -->
    <application
        android:name=".ParseApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--    追加行 START-->
        <service android:name="com.parse.PushService" />
        <!--
        <receiver android:name="com.parse.ParsePushBroadcastReceiver"
            android:exported="false">  -->
        <receiver android:name=".CustomReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.parse.push.intent.RECEIVE" />
                <action android:name="com.parse.push.intent.DELETE" />
                <action android:name="com.parse.push.intent.OPEN" />
            </intent-filter>
        </receiver>

        <receiver android:name="com.parse.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <!--    パッケージ名を変更する必要があります  -->
                <category android:name="YOUR_PACKAGE_NAME" />
            </intent-filter>
        </receiver>
        <!--    送信者IDを変更する必要があります  -->
        <meta-data android:name="com.parse.push.gcm_sender_id"
            android:value="id:YOUR_SENDER_ID" />;
        <!--    追加行 END -->

    </application>

</manifest>

動作確認

プッシュ通知を送信

# curl -s -X POST \
  -H "X-Parse-Application-Id: <Application Id>" \
  -H "X-Parse-Master-Key: <Master Key>" \
  -H "Content-Type: application/json" \
  -d '{
        "where": {
          "deviceType": {
            "$in": [
              "android"
            ]
          }
        },
        "data": {
          "title": "hoge",
          "body": "fuga"
        }
      }'\   http://localhost:1337/parse/push

4.png

感想

今回は、OSSのmBaaSというものを初めて知って使ってみたいということがきっかけで
この記事ではParse Serverの内容で書かせていただきました。

個人的には2年前にGCM+Amazon SNSでプッシュ通知を初めて実装してから、久々のプッシュ通知の実装でした。
GCMがFCMになっていたり、FCMでiOSに対してプッシュ通知ができたりと
特に、FCMを使った場合 Registration ID の更新をSDK側が自動で処理するなど、大きな変化を感じました。

Parser ServerはDocker Hubにコンテナイメージがあるので、
今度できたらhttp://arukas.io で動かせたらな~と思います。

3
3
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
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?