LoginSignup
12
7

More than 5 years have passed since last update.

iOSのサイレントプッシュ通知をAzure Functionsを使って実装してみた

Posted at

概要

iOSの機能であるサイレントプッシュを使って、定期的にアプリ側でバックグランドフェッチして情報を収集したいケースがありましたので、Azure Functions を使ってみた!という話です。

通知を送るのに使ったサービスは Firebase Cloud Messaging なのですが、そのFCMをキックするのに Azure Functions を使いました。サーバレスかつ、全部無料で実装できたのでウマウマです。

構成

ざっくりとしたシステム構成は以下のようにしました。
スクリーンショット 2018-07-29 23.57.02.png

環境

  • Firebase Cloud Messaging
  • Azure Functions
  • iOSアプリ

サイレントプッシュ通知とは

  • iOS7から実装された機能です。サイレントプッシュ通知は名前の通り、アラートや音が出ないのでプッシュを受け取ったことはユーザには分かりません。
  • 通知を受け取った端末は 30秒間 だけ処理を実行することが出来るので、その間にアプリはAPIをリクエストしたりして最新の状態にすることが出来ます。
  • 注意したいのは、端末やアプリの状態によってはサイレントプッシュ通知を受け取っても処理がされない場合があります。例えば以下のケースでは処理が実行されません。
    • マルチタスク機能でユーザ自らアプリをキルした状態の場合
    • iOSの設定でアプリのバックグラウンド更新を有効にしていない場合
    • iOSの設定でバッテリーの低電力モードを有効にしている場合

Azure Functionsを使うメリット

  • タイマー起動ができる
    定期的にサイレントプッシュを送りたいのですが、Azure Functionsならタイマー起動ができるのが魅力的でした。他のAWSやGCP等のFaaSを調べてもタイマー機能があるのはAzureだけでした。
  • Functionsの呼び出しは 月100万リクエストまで無料
    サイレントプッシュは30分単位で送りたかったので、余裕で無料枠で出来ることが分かり選択材料の1つとなりました。
  • 設定が簡単
    実際やってみて短時間で設定が出来ました。サイレントプッシュするだけなら、登録する実行コードはFCMにHttpリクエストするだけです。

iOSアプリ、FCMについて

iOSアプリとFirebase Cloud Messaging の設定ついてはこの記事では割愛します。
代わりに参考にしたリンクを貼っておきます。

Azure Functionsの設定

1、Functionを作るためメニューの「リソースの作成」を選び、「Compute」->「Function App」を選びます。
スクリーンショット 2018-07-18 23.56.58.png

 
2、作成画面に遷移するので、「アプリ名」に好きな名前を入れます(他はデフォルトのままにしました。また、従来課金プランにしないと無料にならなそうです。)
スクリーンショット 2018-07-19 0.00.43.png

 

3、「作成」ボタンをクリックすると、デプロイが始まるので終わるまで待ちます。

 

4、デプロイが終わると通知が来ますので、「リソースへ移動」を選びます。
スクリーンショット 2018-07-19 0.05.38.png

 

5、次にメニューの関数の横にある「+」ボタンを選びます。すると。シナリオと言語を選ぶ画面が表示されるのですが、下部に「カスタム関数」を選択します。
スクリーンショット 2018-07-19 0.07.43.png

 

6、テンプレートが表示されるので、「Time trigger」を選択します。
スクリーンショット 2018-07-19 0.11.16.png

 
7、言語、関数名、タイマースケジュールの設定が表示されるので好きな設定に変更します。(ここでは言語はjavascriptで、タイマーを30分周期にしたかったので以下のように設定をしました)
スクリーンショット 2018-07-19 0.12.31.png

 

8、ここまで出来たら次はHTTPリクエストを簡単に実装するため、Node.jsのパッケージをインストールします。https://{function_app_name}.scm.azurewebsites.net にブラウザでアクセスします。自分の場合だと https://silentpushtest.scm.azurewebsites.net になります。(ここについて詳しく知りたい方はAzure Functions の JavaScript 開発者向けガイドが参考になるかと思います。)
 
9、すると、以下の画面になると思うので、メニューの「Debug Console」-> 「CMD」を選択します。
スクリーンショット 2018-07-30 0.44.52.png

 

10、コンソール画面に遷移するので、D:\home\site\wwwrootまでディレクトリを下っていきます。そしたら npm init を実行します。質問の回答はデフォルトのままにしました(ひたすらEnter)

D:\home\site\wwwroot> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (wwwroot) 
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to D:\home\site\wwwroot\package.json:

{
  "name": "wwwroot",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this ok? (yes) 

11、package.jsonが作られていればOKです。次に requestパッケージをインストールします。

  D:\home\site\wwwroot> npm install request --save
  wwwroot@1.0.0 D:\home\site\wwwroot
  `-- request@2.87.0 

(省略)

12、さて、Functionの設定に戻ります。先ほど作成したFunctionを選ぶとソースコードを実装する画面になります。
スクリーンショット 2018-07-30 1.00.15.png

 

13、ソースコードを以下にようにします。ServerKey はFirebaseの設定画面から取得することができます。TopicName はアプリ側で購読させたTopic名を指定してください。

module.exports = function (context, myTimer) {
  var timeStamp = new Date().toISOString();

  if (myTimer.isPastDue) {
    context.log('JavaScript is running late!');
  }

  var request = require('request');

  var options = {
    url: 'https://fcm.googleapis.com/fcm/send',
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'key={ServerKey}'
    },
    json: {
      to: '/topics/{TopicName}',
      priority: 'high',
      content_available: true
    }
  };

  request.post(options, function (error, response, body) {
    context.log("Response Code : "+response.statusCode);
  });

  context.log('JavaScript timer trigger function ran!:', timeStamp);
  context.done();
};

14、「実行」ボタンを押すことで試しにサイレントプッシュが送れるか確認することができます。実行してみて問題がなければ「保存」ボタンを押して Functionの設定は以上で終わりです!

最後に

説明が長くなってしまいましたが、やってることはほぼGUI操作で終わるのでとても楽でした。
なりより、サーバを持たないかつ、無料で実装出来たのが非常に良かったです!

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