<span style="font-size: 20%">ニフティクラウドmobile backend レベルアップセミナー</span><br>クーポン配信<br>アプリを作ろう</span><br><span style="font-size: 60%">【Monaca編】</span>

## 事前準備
* ニフティクラウドmobile backendのアカウント登録がお済みでない方は、[ホームページ](http://mb.cloud.nifty.com/about.htm)右上にある「無料登録」ボタンをクリックして、アカウント登録を実施してください。

![mBaaS検索.png](https://qiita-image-store.s3.amazonaws.com/0/112032/1c4f2a30-aab6-b13f-6e0e-9fc40761da5e.png)

-----

## 事前準備
![mBaaS無料登録.png](https://qiita-image-store.s3.amazonaws.com/0/112032/a1f242b4-04e8-fb20-6057-24349fff62e4.png)

-----
## ニフティクラウド mobile backendとは
### サービス紹介

スマホアプリで汎用的に実装される以下のような機能を、クラウドサービスとして提供しているサービスです.

![13840482_10154409121150956_1264478871_o.png](https://qiita-image-store.s3.amazonaws.com/0/18698/6a54837b-9a55-aa5a-fa55-e008c0d582f0.png)

Monaca環境も対応しており、JavascriptSDKを利用することで上記の機能簡単実装できます。

-----
## ニフティクラウド mobile backendとは
### SDKの特徴

* SDKのインストールが必要　（済み）
  * 今回は実装済み
  * 参考：[クイックスタート](http://mb.cloud.nifty.com/doc/current/introduction/quickstart_monaca.html)

-----
## ニフティクラウド mobile backendとは
### SDKの特徴

* 利用する前に、初期化が必要
  * 後ほど実装案内
    
```js
var ncmb = new NCMB("YOUR_APPLICATIONKEY","YOUR_CLIENTKEY");
```

-----
## ニフティクラウド mobile backendとは
### SDKの特徴
    
* サーバへリクエストする際、Javascriptは基本的に非同期処理として実行されます。
* SDKの代表利用例を紹介します。
    * オブジェクトを登録する
    * Promise形式で実装されています. 
    * then, catchでそれぞれ成功／失敗の時の処理を定義します。

-----
## ニフティクラウド mobile backendとは
### SDKの特徴


```js
// クラスのBookを作成
var Book = ncmb.DataStore("Book");

// データストアへの登録
var book = new Book();
book.set("message", "Hello, NCMB!");
book.save()
    .then(function(){
          // 保存に成功した場合の処理
    })
    .catch(function(err){
          // 保存に失敗した場合の処理
    });
```

-----
## ハンズオンセミナーの概要

* 「mBaaS Shop List」アプリ
  * クーポン配信アプリをイメージした「mBaaS Shop List」アプリの作成を通して、mBaaSの機能を理解していきます
  * mBaaSの連携部分をコーディングし、アプリを完成させ、次の内容を実現していきます


-----
## ハンズオンセミナーの概要

* 「mBaaS Shop List」アプリ
 * 会員登録をするとお店情報を見ることができます
 * お店のお気に入り登録ができ、お気に入り登録をしたお店からプッシュ通知で届きます
 * 性別や都道府県限定のプッシュ通知ができます
 * お店からのプッシュ通知でクーポンを直接配信することができます


-----
## ハンズオンセミナーの概要

![zentai.png](https://qiita-image-store.s3.amazonaws.com/0/18698/43b61d3d-f138-1bbf-af07-5d766e571727.png)



-----
## ハンズオンセミナーの具体的なの流れ
1. ハンズオンの準備
1. 会員管理機能の作成
1. Shop情報の設定
1. お気に入り登録機能の作成
1. プッシュ通知を送信①セグメント配信
1. プッシュ通知を送信②リッチプッシュ

-----
## ハンズオンの準備
__Monacaプロジェクトをダウンロード__

* 下記リンクをクリックして、ZIPファイルでダウンロードしてください

　　　 __[MonacaAdvancePush](https://github.com/ncmbadmin/MonacaAdvancePush/archive/handson_version.zip)__

-----
## ハンズオンの準備
__Monacaプロジェクトをインポート__

* [Monaca](https://ja.monaca.io/)でプロジェクトをインポートします。

![import.png](https://qiita-image-store.s3.amazonaws.com/0/18698/83b17cfd-4e7f-e4f8-6db8-6c0dec36ab1d.png)


-----
## ハンズオンの準備
__プロジェクトにあらかじめ実施していること__

* mBaaSのJavascript SDKをインストール済み ( *Javascript SDK v.2.1.2* )
* mBaaSのプッシュ通知Cordovaプラグインをインストール済み ( *Monaca NCMB Push plugin v.2.0.2* )

-----
## ハンズオンの準備
__プロジェクトにあらかじめ実施していること__

* mBaaSとの連携以外の処理のコーディング
 * アプリのデザインを[jQuery Mobile](https://jquerymobile.com/)ベースで作成し、画面遷移、ボタン処理はコーディングしています( *index.html* )

-----
## ハンズオンの準備
__mBaaSの準備__

* [mBaaS](http://mb.cloud.nifty.com)にログインしてアプリを作成します
![mBaaSアプリ作成.png](https://qiita-image-store.s3.amazonaws.com/0/112032/b23d2eb1-c06f-fdee-ebbd-1c8c3ce95974.png)


-----
## ハンズオンの準備
__APIキーの設定とSDKの初期化__

* `www/js/app.js`を開きます
* 一番最初に実行される処理を実装します

-----
## ハンズオンの準備
__APIキーの設定とSDKの初期化__

以下のコメントの直下に初期化コードを追加します。

BEFORE

```js:app.js
 // 【mBaaS】 APIキーの設定とSDKの初期化
```

AFTER

```js:app.js
 // 【mBaaS】 APIキーの設定とSDKの初期化
var appKey    = "YOUR_APP_KEY";
var clientKey = "YOUR_CLIENT_KEY";
var ncmb = new NCMB(appKey,clientKey);
```

-----
## ハンズオンの準備
__APIキーの設定とSDKの初期化__

* 「`YOUR_APP_KEY`」，「`YOUR_CLIENT_KEY`」の部分にはアプリ作成時に発行されたAPIキーに書き換えてください
 * APIキーは、mBaaSのダッシュボードから「アプリ設定」→「基本」にあります

![APIkey.png](https://qiita-image-store.s3.amazonaws.com/0/18698/2ae55e24-fc62-77e6-886a-4bc5a3d92256.png)



----
## 会員管理機能の作成

__mBaaSの設定__

* 会員管理設定の「メールアドレス/パスワード認証」を許可します
    * 「許可する」と選択し、保存します。

![mBaaS会員設定.png](https://qiita-image-store.s3.amazonaws.com/0/112032/43615f7b-70e2-da33-1f30-3d18a7117818.png)

----
## 会員管理機能の作成

__会員管理①：「会員登録画面」会員登録用メールを要求する__

![1_2a.png](https://qiita-image-store.s3.amazonaws.com/0/18698/fcbe11b1-e5a2-44d6-e620-e3fbda230a83.png)

----
## 会員管理機能の作成

__会員管理①：「会員登録画面」会員登録用メールを要求する__

HTMLフォームコードは `index.html`にて確認できます。

```html:index.html
    <!-- [2 SIGNUP] 会員ログインリクエストページ -->
    <div data-role="page" id="SignupPage" data-theme="t">
    <header data-role="header" data-position="fixed" data-theme="t">
        <h1>mBaaSショップ</h1>
    </header>
        <section data-role="content">
        <h1>新規登録</h1>    
      メールアドレス
        <input type="text" id="signup_mailaddress">  
        <a href="#" id="SignupBtn" data-role="button" data-inline="false" data-theme="e">送信</a>
        <a href="#LoginPage" data-role="button" data-mini="true" data-inline="true" data-theme="e">戻る</a>
      </section>
    </div>
```

----
## 会員管理機能の作成
__会員管理①：「会員登録画面」会員登録用メールを要求する__

* `app.js`の`onSignupBtn()`を開きます
* 会員登録処理を実装します
 * 以下のコメントの直下にコードを追加します。

BEFORE

```js:app.js
    // 【mBaaS：会員管理①】会員登録用メールを要求する 
```


AFTER

```js:app.js
    // 【mBaaS：会員管理①】会員登録用メールを要求する 
    var mailaddress = $("#signup_mailaddress").val();
    ncmb.User.requestSignUpEmail(mailaddress)
         .then(function(data){
            // 会員登録用メールの要求成功時の処理
         })
         .catch(function(err){
            // 会員登録用メールの要求失敗時の処理
         });
```

----
## 会員管理機能の作成
__会員管理①：会員登録用メールを要求する__

* それぞれ処理を追記します

成功時の処理

```js
            // 会員登録用メールの要求成功時の処理
            alert("リクエストを送信しました！メールをご確認ください。");
            $.mobile.changePage('#LoginPage');
```

失敗時の処理

```js
            // 会員登録用メールの要求失敗時の処理
            alert("リクエスト失敗！次のエラー発生: " + err);
            $.mobile.changePage('#LoginPage');
```

----
## 会員管理機能の作成
__会員管理②：メールアドレスとパスワードでログイン__

![2.png](https://qiita-image-store.s3.amazonaws.com/0/18698/8ddb8923-3b23-58d8-8573-eafefe2270be.png)

----
## 会員管理機能の作成
__会員管理②：メールアドレスとパスワードでログイン__

HTMLフォームコードは `index.html`にて確認できます。

```html:index.html
    <!-- [1 LOGIN] ログインページ -->
    <div data-role="page" id="LoginPage" data-theme="t">
        <header data-role="header" data-position="fixed" data-theme="e">
            <h1>mBaaSショップ</h1>
        </header>
        <section data-role="content">
            <center><h1>mBaaSショップ</h1></center>
                メールアドレス
            <input type="text" id="login_mailaddress">
                パスワード
            <input type="password" id="login_password">
                新規登録？
            <a href="#SignupPage" data-role="button" data-mini="true" data-inline="true" data-theme="e">会員登録</a>
            <a href="#" id="LoginBtn" data-role="button" data-inline="false" data-theme="e">ログイン</a>
        </section>
    </div>
```

----
## 会員管理機能の作成
__会員管理②：メールアドレスとパスワードでログイン__

* `app.js`の`onLoginBtn()`を開きます
* ログイン処理を実装します
 * 以下のコメントの直下にコードを追加します。

BEFORE

```js:app.js
    //【mBaaS：会員管理②】メールアドレスとパスワードでログイン 
```

AFTER

```js:app.js
    //【mBaaS：会員管理②】メールアドレスとパスワードでログイン 
    // 入力したメールアドレスの値
    var mailaddress = $("#login_mailaddress").val();
    // 入力したパスワードの値
    var password = $("#login_password").val();
    
    // メールアドレスとパスワードでログイン処理実施
    ncmb.User.loginWithMailAddress(mailaddress, password)
        .then(function(user) {
            // ログイン成功時の処理
        })
        .catch(function(error) {
            // ログイン失敗時の処理
        });
```

----
## 会員管理機能の作成
__会員管理②：メールアドレスとパスワードでログイン__

* それぞれ処理を追記します

```js
            // ログイン成功時の処理
            alert("ログイン成功");
            currentLoginUser = ncmb.User.getCurrentUser();
            if(currentLoginUser.nickname) {
                showShopList();
            } else {
                // ユーザ情報登録画面遷移
                $.mobile.changePage('#RegisterPage');
            }
```

----
## 会員管理機能の作成
__会員管理②：メールアドレスとパスワードでログイン__

* それぞれ処理を追記します

```js
            // ログイン失敗時の処理
            alert("ログイン失敗！次のエラー発生: " + error);
```

----
## 会員管理機能の作成
__動作確認①ログインをしてみましょう__

* デバッグについて（プッシュ通知がない場合）
 * 方法１（monacaデバッガーツール） [iOS](https://itunes.apple.com/jp/app/monaca/id550941371?mt=8) & [Android](https://play.google.com/store/apps/details?id=mobi.monaca.debugger&hl=ja)を利用

----
## 会員管理機能の作成
__動作確認①ログインをしてみましょう__

* デバッグについて（プッシュ通知がない場合）
 * 方法２（monaca IDEのプレビュー機能を利用）

![preview.png](https://qiita-image-store.s3.amazonaws.com/0/18698/acd8c78b-675f-73f7-4f67-77410158e37f.png)


----
## 会員管理機能の作成
__動作確認①ログインをしてみましょう__


* ログイン画面で「会員登録」をタップします
* 会員登録画面でメールアドレスを入力し、「登録メールを送信」をタップします

![3_1.png](https://qiita-image-store.s3.amazonaws.com/0/18698/0e2e9b4f-6d4e-029a-d7ed-5ea3a6bbc0bd.png)



----
## 会員管理機能の作成
__動作確認①ログインをしてみましょう__

* 会員登録メールが届くので、パスワード設定します
 
![動作確認①パスワード登録.png](https://qiita-image-store.s3.amazonaws.com/0/112032/82f0e261-4e10-9c0c-fe85-90c2db57aae9.png)

----
## 会員管理機能の作成
__動作確認①ログインをしてみましょう__

* 再びログイン画面に戻り「メールアドレス」と「パスワード」でログインします
* ログインが成功するかどうかを確認してください

----
## 会員管理機能の作成
__動作確認①ログインをしてみましょう__

* ダッシュボードでも会員登録されていることを確認しましょう。

![user_confirm.png](https://qiita-image-store.s3.amazonaws.com/0/18698/c22235c8-b731-2640-15ba-d05e872f13ba.png)


----
## 会員管理機能の作成
__会員管理③：ユーザー情報更新__

![4_2.png](https://qiita-image-store.s3.amazonaws.com/0/18698/7c851c43-5562-0824-f4a1-dbd365019ae9.png)

----
## 会員管理機能の作成
__会員管理③：ユーザー情報更新__

HTMLフォームコードは `index.html`にて確認できます。

```html:index.html
  <!-- [3 REGISTER] 会員登録ページ -->
  <div data-role="page" id="RegisterPage" data-theme="t">
    <header data-role="header" data-position="fixed" data-theme="e">
        <h1>mBaaSショップ</h1>
    </header>
        <section data-role="content">
        <h1>新規会員登録</h1>
      ニックネーム
        <input type="text" id="reg_nickname">
        <div class="ui-field-contain">
            <fieldset data-role="controlgroup">
              <legend>性別</legend>
              <input id="reg_male" name="reg_gender" type="radio" value="男性" />
              <label for="reg_male">男性</label>
              <input id="reg_female" name="reg_gender" type="radio" value="女性" />
              <label for="reg_female">女性</label>
            </fieldset>
        </div>
      都道府県
        <input type="text" id="reg_prefecture">
        <a href="#" id="RegisterBtn" data-role="button" data-inline="false" data-theme="e">登録</a>
      </section>
  </div>
```

----
## 会員管理機能の作成
__会員管理③：ユーザー情報更新__

* `app.js`の`onRegisterBtn()`を開きます
* 初回のみ表示されるユーザー情報登録画面に入力した情報をmBaaSのユーザー情報に追加する処理を実装します
 * 以下のコメントの直下にコードを追加します。

BEFORE

```js:app.js
    //【mBaaS：会員管理③】ユーザー情報更新-
```

AFTER

```js:app.js
    //【mBaaS：会員管理③】ユーザー情報更新-
    //入力フォームからnickname, prefecture, genderを値セット
    var nickname = $("#reg_nickname").val();
    var prefecture = $("#reg_prefecture").val();
    var gender = $('input[name=reg_gender]:checked').val();
    
    // currentLoginUserユーザー情報を設定
    currentLoginUser.nickname = nickname;
    currentLoginUser.prefecture = prefecture;
    currentLoginUser.gender = gender;
    currentLoginUser.favorite = [];
    
    // user情報の更新
    currentLoginUser.update()
                    .then(function(user) {
                         // 更新成功時の処理
                    })
                    .catch(function(error) {
                        // 更新失敗時の処理
                    });
```

----
## 会員管理機能の作成
__会員管理③：ユーザー情報更新__

* それぞれ処理を追記します

```js
     // 更新成功時の処理
     // 【mBaaS：プッシュ通知②】installationにユーザー情報を紐づける
     alert("会員情報登録に成功");
     //お店一覧画面遷移
     showShopList();
```

----
## 会員管理機能の作成
__会員管理③：ユーザー情報更新__

* それぞれ処理を追記します

```js
     // 更新失敗時の処理
     alert("会員情報登録に失敗！次のエラー発生：" + error);
```


----
## 会員管理機能の作成
__動作確認②ユーザー情報更新__

* 会員情報を入力し、登録しましょう。

![confirm2.png](https://qiita-image-store.s3.amazonaws.com/0/18698/1c57c8c9-1018-57ea-ea71-27811ead487f.png)

----
## 会員管理機能の作成
__動作確認②ユーザー情報更新__

* 登録した情報を確認ページでみてみましょう

![mypage_confirm.png](https://qiita-image-store.s3.amazonaws.com/0/18698/07137958-9a94-3f03-800f-77d5dfb3d8b3.png)


-----
## Shop情報の設定
__mBaaSにShop情報を用意する（データストア）__

* 以下の手順でデータストアに「Shop」という名前のクラスを作成します
 * ニフティクラウド mobile backendのダッシュボードから「データストア」を開く
 * 「＋作成▼」ボタンをクリックし、「インポート」をクリックします
 * クラス名に「__Shop__」と入力します

-----
## Shop情報の設定
__mBaaSにShop情報を用意する（データストア）__
 
 * ダウンロードしたプロジェクトにあるSettingフォルダ内の「__Shop.json__」を選択してアップロードします

![ShopClass.png](https://qiita-image-store.s3.amazonaws.com/0/112032/067cadbb-8fca-ad69-179f-afadfed739ee.png)

-----
## Shop情報の設定
__mBaaSにShop情報を用意する（データストア）__

* ダッシュボードでデータがインポートされていることを確認しましょう。

![shopkakunin.png](https://qiita-image-store.s3.amazonaws.com/0/18698/4fdf4588-da69-09c5-9d56-c2ac41bc573e.png)


-----
## Shop情報の設定
__mBaaSにShop情報を用意する（ファイルストア）__

* 以下の手順で各icon・Shop画面・リッチプッシュで使用する画像をmBaaSに設定します
 * ニフティクラウド mobile backendのダッシュボードから「ファイルストア」を開く
 * 「↑アップロード」ボタンをクリックします
 * ダウンロードしたサンプルプロジェクトにあるSettingフォルダ内の「icon」「Shop」「Sale」内にあるファイルをすべてをアップロードします

-----
## Shop情報の設定
__mBaaSにShop情報を用意する（ファイルストア）__

![imageUpload.png](https://qiita-image-store.s3.amazonaws.com/0/112032/d319acce-9409-b8a5-dbf5-428804dd9252.png)

-----
## Shop情報の設定
__mBaaSにShop情報を用意する（ファイルストア）__

* ファイルストアでファイルがアップロードされていることを確認しましょう。

![file_kakunin.png](https://qiita-image-store.s3.amazonaws.com/0/18698/08457251-b993-3bd6-c288-119fe5984d6a.png)


-----
## Shop情報の設定
__データストア：「Shop」クラスのデータを取得__

* これからデータストアに入っているショップデータの取得を実装していきます。

![mBaaS_ShopData.PNG](https://qiita-image-store.s3.amazonaws.com/0/112032/b5840cc7-634d-f9b7-ff42-9a1888fd358c.png)

-----
## Shop情報の設定
__データストア：「Shop」クラスのデータを取得__

* `app.js`の`showShopList()`を開きます
* インポートしたShopクラスのデータを取得する処理を実装します

-----
## Shop情報の設定
__データストア：「Shop」クラスのデータを取得__

HTMLフォームコードは `index.html`にて確認できます。

```html:index.html
 <!-- [5 TOP] メインページ -->
  <div data-role="page" id="TopPage" data-theme="t">
  <-- 省略 -->
        <ul data-role="listview" data-theme="e" id="listShop"  >
        </ul>
  <-- 省略 -->
  </div>
```

-----
## Shop情報の設定
__データストア：「Shop」クラスのデータを取得__

BEFORE

```js:app.js
    //【mBaaS：データストア】「Shop」クラスのデータを取得
```

AFTER

```js:app.js
    // 【mBaaS：データストア】「Shop」クラスのデータを取得
    // 「Shop」クラスのクエリを作成
    var ShopClass = ncmb.DataStore("Shop");
    
    //  データストアを検索
    ShopClass.fetchAll()
        .then(function(shops) {
            // 検索成功時の処理
        })
        .catch(function(error) {
            // 検索失敗時の処理
        }); 
```

-----
## Shop情報の設定
__データストア：「Shop」クラスのデータを取得__

* それぞれ処理を追記します

```js
            // 検索成功時の処理
            shopList = convertShopList(shops);
            
            // shopArrayに取得しやすいショップのobjectIdと「Shop」クラスの情報を保持
            shopArray = shops;
            
            // listShopの内容を設定
            for (var i = 0; i < shops.length; i++) {
                var shop = shops[i];
                var tmpStr = '<li class="ui-li-has-thumb"><a id="ShopBtn" href="#" onclick="showShopDetail(\'' + shop.objectId + '\');"><img src="'+ publicFileUrl + shop.icon_image +'" />'
            + shop.name + '</a></li>';
                $("#listShop").append(tmpStr);
            }
            
            // listShopの内容を更新
            $('#listShop').listview('refresh');
```

-----
## Shop情報の設定
__データストア：「Shop」クラスのデータを取得__

* それぞれ処理を追記します

```js
// 検索失敗時の処理
alert(error.message);
```

-----
## Shop情報の設定
__ファイルストア：icon画像の取得__

以下のように画像を表示する設定します。

![5.png](https://qiita-image-store.s3.amazonaws.com/0/18698/b3659437-b8fa-b6a9-bde6-40fae0c3a1a0.png)


-----
## Shop情報の設定
__ファイルストア：icon画像の取得__

* 今回は公開ファイルを利用して、アプリの画像を取得します
* 公開ファイルとは
    * 「公開ファイル」機能とは、ファイルストアに保存した画像をリンクでアクセスできるようにする機能です
*  ファイルストアに登録した画像を「公開ファイル」にします

-----
## Shop情報の設定
__ファイルストア：icon画像の取得__

* 公開ファイルの設定を有効にします

![publicFile](https://qiita-image-store.s3.amazonaws.com/0/112032/539c2789-54d6-c4a5-2842-c994b8cd8e46.png)

-----
## Shop情報の設定
__ファイルストア：icon画像の取得__

* リンクは以下のように作成できます

https://mb.api.cloud.nifty.com/2013-09-01/applications/*****アプリケーションID*****/publicFiles/*****ファイル名*****

-----
## Shop情報の設定
__ファイルストア：icon画像の取得__

* `app.js`の「YOUR_APP_ID」をmBaaSのアプリケーションIDに書き換えます

```js:app.js
var applicationID = "YOUR_APP_ID";
```

-----
## Shop情報の設定
__ファイルストア：icon画像の取得__

* 「ダッシュボード」を選択し、URLから「YOUR_APP_ID」を確認してください。

![appID](https://qiita-image-store.s3.amazonaws.com/0/112032/c6409f1a-41bb-8f99-b36f-35355765b46b.png)

-----
## Shop情報の設定
__ファイルストア：icon画像の確認__

![5.png](https://qiita-image-store.s3.amazonaws.com/0/18698/80ca052c-28fe-0baa-be7a-a203d14dade0.png)



-----
## Shop情報の設定
__ファイルストア：Shop画面画像の取得__

上記同様、ショップ詳細画像の表示を実装します。

![pix2.png](https://qiita-image-store.s3.amazonaws.com/0/18698/cab21953-72df-ef98-9eb4-f4cf44fe4fbb.png)



-----
## Shop情報の設定
__ファイルストア：Shop画像の取得__

* `app.js`の`showShopDetail()`を開きます
* Shop画面に各ショップの画像をmBaaSから取得して表示する処理を実装します

-----
## Shop情報の設定
__ファイルストア：Shop画像の取得__

BEFORE

```js:app.js
   // 【mBaaS：ファイルストア②】Shop画像の取得
```

AFTER

```js:app.js
   // 【mBaaS：ファイルストア②】Shop画像の取得
   currentShopId = shopId;
   var shopTmp = shopList[shopId]; 
   $("#shopName").text(shopTmp.name);
   $("#shopImage").attr("src" , publicFileUrl + shopTmp.shop_image); 
   // お気に入り登録されている場合の表示設定
   if (currentLoginUser.favorite.indexOf(shopId) >= 0) {
        //お気に入り登録された場合の♥︎表示
        $("#favoriteImage").attr("src" , "images/favorite.png");
        //お気に入り登録ボタンを非アクティブ表示
        $("#FavoriteBtn").addClass('ui-disabled');
   }else{
        //お気に入り登録された場合の♡表示
        $("#favoriteImage").attr("src" , "images/nofavorite.png");
        //お気に入り登録ボタンをアクティブ表示
        $("#FavoriteBtn").removeClass('ui-disabled');
   }
```

-----
## Shop情報の設定
__動作確認③会員情報登録とShop情報表示__

* トップ画面が表示されます
  * このとき、 画面に「icon画像」「Shop名」が表示されます
* Shopを１つ選んでタップします
  * mBaaSに登録されているimageにアクセスし、Shopページ（画像）が表示されます
* 会員ページをタップします
  * 初回登録画面で登録した内容と、ログイン用のアドレスを表示しています

-----
## Shop情報の設定
__動作確認③会員情報登録とShop情報表示__

![test_new1.png](https://qiita-image-store.s3.amazonaws.com/0/18698/dbcd7bb5-5ebb-9330-7795-3aaeb2646879.png)



-----
## お気に入り登録機能の作成

__お気に入り機能について__

* お気に入り機能は好きなShopをお気に入りとして保存できる機能です
 * 「お気に入り」画面と「Shop」画面で登録可能です

-----
## お気に入り登録機能の作成

__お気に入り機能について__

* 「お気に入り」画面ではSwitchのON/OFFを設定し、「お気に入りを更新する」ボタンで設定します
* ショップ詳細画面ではまだお気に入り登録していない場合、「お気に入りを登録」をタップすることでShop単位で設定できます
 * 「♥」…ON　「♡」…OFF

-----
## お気に入り登録機能の作成

__お気に入り機能について__

![favorite1.png](https://qiita-image-store.s3.amazonaws.com/0/18698/38be6f3e-31bc-612e-12a0-2e2cee50f7f3.png)



-----
## お気に入り登録機能の作成

__会員管理④：ユーザー情報の更新(お気に入り画面)__

* `app.js`の`onUpdateFavoriteBtn()`を開きます
* mBaaSの会員データとして保持していた「favorite」データを、お気に入り画面で設定したデータに更新する処理を実装します
 * コメントの直下に追加します。

-----
## お気に入り登録機能の作成

__会員管理④：ユーザー情報の更新(お気に入り画面)__

BEFORE

```js:app.js
    // 【mBaaS：会員管理④】ユーザー情報の更新
```

AFTER

```js:app.js
    // 【mBaaS：会員管理④ユーザー情報の更新
        
    //ONを設定している項目を取得
    var array = [];
    $('[name=favorite_shop]').each(function() {
        var tmp = $(this).val();
        if (tmp != "off") {
            array.push(tmp);
        }
    });

    // ログイン中のユーザーの更新favoriteを設定
    currentLoginUser.favorite = array;

    // ユーザー情報を更新
    currentLoginUser.update()
                    .then(function(currentLoginUser) {
                            // 【mBaaS：プッシュ通知②】installationにユーザー情報を紐づける
                            alert("お気に入り情報更新に成功しました");
                            showFavorite();
                    })
                    .catch(function(error) {
                        // 更新に失敗した場合の処理
                        alert("お気に入り登録に失敗！次のエラー発生：" + error);
                    });

```


-----
## お気に入り登録機能の作成

__会員管理⑤：ユーザー情報の更新(Shop画面)__

* `app.js`の`onFavoriteBtn()`を開きます
* 同様にmBaaSの会員データとして保持していた「favorite」データを、Shop画面で設定したデータに更新する処理を実装します

-----
## お気に入り登録機能の作成

__会員管理⑤：ユーザー情報の更新(Shop画面)__

BEFORE

```js:app.js
    // 【mBaaS：会員管理⑤】ユーザー情報の更新
```

AFTER

```js:app.js
    // 【mBaaS：会員管理⑤】ユーザー情報の更新
    
    // ログイン中のユーザーのお気に入り情報（favorite）を設定
    currentLoginUser.favorite.push(currentShopId);

    // ユーザー情報を更新
    currentLoginUser.update()
                    .then(function(currentLoginUser) {
                            // 【mBaaS：プッシュ通知④】installationにユーザー情報を紐づける
                            // 更新に成功した場合の処理
                            alert("お気に入り登録に成功");
                            showShopDetail(currentShopId);
                    })
                    .catch(function(error) {
                            // 更新に失敗した場合の処理
                            alert("お気に入り登録に失敗！次のエラー発生：" + error);
                    });
```


-----
## お気に入り登録機能の作成
__動作確認④お気に入り情報登録・更新__

* ログインをするとトップ画面が表示されます
* 画面下の「お気に入り」をタップします
* お気に入り画面が表示されるので、登録してみましょう
* 各Shop画面でも同様に登録してみましょう
* お気に入りが反映しているかどうかを確認してください
 
-----
## お気に入り登録機能の作成
__動作確認④お気に入り情報登録・更新__

![favorite_check.png](https://qiita-image-store.s3.amazonaws.com/0/18698/81769caa-e34f-a192-6730-8704ffbfe165.png)



-----
## プッシュ通知を送信

__このあとのデバッグについて__

* 以下の用意が必要です
 * デバッグ用の実機 (iOS, Android)
 * プッシュ通知用証明書 (iOSの場合)
 * プッシュ通知用APIキー (Androidの場合)

* APIキー、証明書の取得がまだの場合は下記をご参照ください
 * [【サンプル】アプリにプッシュ通知を組み込もう！](https://github.com/NIFTYCloud-mbaas/MonacaPushApp)

-----
## プッシュ通知を送信

__mBaaSの設定（iOS）__

* プッシュ通知の許可とAPNsの証明書(p12形式)のアップロードを行います

![mBaaSプッシュ通知設定.png](https://qiita-image-store.s3.amazonaws.com/0/112032/7a2054e1-9469-858b-f8d7-4792e7469e1b.png)


-----
## プッシュ通知を送信

__mBaaSの設定（Android）__

* プッシュ通知の許可とAPIキーの設定を行います

![android_push.png](https://qiita-image-store.s3.amazonaws.com/0/18698/82e2d98d-6999-90b2-e4a3-413f79e60779.png)



-----
## プッシュ通知を送信

__プッシュ通知①：デバイストークンの取得__

* `app.js`の`function()`を開きます
* 以下のコメントの直下にコードを追加

BEFORE

```js:app.js
    // 【mBaaS：プッシュ通知①】デバイストークンの取得し、サーバへ登録処理
```

AFTER

```js:app.js
    // 【mBaaS：プッシュ通知①】デバイストークンの取得し、サーバへ登録処理
    document.addEventListener("deviceready", function(){
            // デバイストークンを取得してinstallationに登録する
            window.NCMB.monaca.setDeviceToken(
                appKey,
                clientKey,
                project_number
            );
            
            setTimeout(function(){
                //currentInstallationの情報を取得
                window.NCMB.monaca.getInstallationId(
                    function(id) {
                        //JavaScript SDKのInstallationクラスを利用して端末情報を取得
                        ncmb.Installation.fetchById(id)
                                         .then(function(installation){
                                            //サーバから取得した結果をcurrentInstallationに保存
                                            currentInstallation = installation;
                                          })
                                         .catch(function(err){
                                            // エラー処理
                                          });
                    }
                ); 
        	},20000);
            
        },false);
```



-----
## プッシュ通知を送信

__プッシュ通知①：デバイストークンの取得__

* Androidの場合、`app.js`で指定している`PROJECT_NUMBER` を設定します。

![androidprojnum.png](https://qiita-image-store.s3.amazonaws.com/0/18698/78297862-ca99-f2a1-1bed-bf677de9ddbd.png)


-----
## プッシュ通知を送信①セグメント配信

__プッシュ通知②：installationにユーザー情報を紐づける__

* `app.js`の`onRegisterBtn()`を開きます
* セグメント配信のために必要なユーザー情報をinstallationに紐付けるための処理を実装します
 * 実装箇所は「【mBaaS：会員管理③】ユーザー情報更新」の更新成功時の処理内です
 * 以下のコメントの直下にコードを変更します（追記ではありません）
 
BEFORE

```js:app.js
// 【mBaaS：プッシュ通知②】installationにユーザー情報を紐づける
alert("会員情報登録に成功");
//お店一覧画面遷移
showShopList();
```

AFTER

```js:app.js
// 【mBaaS：プッシュ通知②】installationにユーザー情報を紐づける
if (currentInstallation) {
    // ユーザー情報を設定
    currentInstallation.prefecture = prefecture;
    currentInstallation.gender = gender;
    currentInstallation.favorite = [];
    
    // installation情報の更新
    currentInstallation.update()
        .then(function(installation) {
            // installation更新成功時の処理                                    
        })
        .catch(function(error) {
            // installation更新失敗時の処理
        });
}else {
    alert("会員情報登録に成功");
    //お店一覧画面遷移
    showShopList();
}

```

-----
## プッシュ通知を送信①セグメント配信

__プッシュ通知②：installationにユーザー情報を紐づける__

* それぞれ処理を追記します


```js
 // installation更新成功時の処理
 alert("会員情報登録に成功");
 //お店一覧画面遷移
 showShopList();
```


-----
## プッシュ通知を送信①セグメント配信

__プッシュ通知②：installationにユーザー情報を紐づける__

* それぞれ処理を追記します

```js
// installation更新失敗時の処理
alert("installation更新(ユーザー登録)に失敗しました:+error.code)")
```

-----

## プッシュ通知を送信①セグメント配信

__プッシュ通知③：installationにユーザー情報を紐づける__

* 同様に、お気に入り画面・Shop画面でお気に入り情報が更新されるたびに、installation情報も書き換えます

-----

## プッシュ通知を送信①セグメント配信

__プッシュ通知③：installationにユーザー情報を紐づける__

* `app.js`の`onUpdateFavoriteBtn()`を開きます
* 以下のコードを更新します（追記ではありません）

BEFORE

```js:app.js
// 【mBaaS：プッシュ通知③】installationにユーザー情報を紐づける
alert("お気に入り情報更新に成功しました");
showFavorite();
```

AFTER

```js:app.js
// 【mBaaS：プッシュ通知③】installationにユーザー情報を紐づける
    
// 更新に成功した場合の処理
if (currentInstallation) {
    
    // お気に入り情報を設定
    currentInstallation.favorite = array;
    
    // installation情報の更新
    currentInstallation.update()
        .then(function(installation) {
            // installation更新成功時の処理
            alert("お気に入り情報更新に成功しました");
            showFavorite();
        })
        .catch(function(error) {
            // installation更新失敗時の処理
        });                    
}
else {
    // installation更新成功時の処理
    alert("お気に入り情報更新に成功しました");
    showFavorite();
}
```

-----

## プッシュ通知を送信①セグメント配信

__プッシュ通知④：installationにユーザー情報を紐づける__

* `app.js`の`onFavoriteBtn()`を開きます
* 以下のコードを更新します（追記ではありません）

BEFORE

```js:app.js
// 【mBaaS：プッシュ通知④】installationにユーザー情報を紐づける
alert("お気に入り登録に成功");
showShopDetail(currentShopId);
```

AFTER

```js:app.js
// 【mBaaS：プッシュ通知④】installationにユーザー情報を紐づける
if(currentInstallation ){
 // お気に入り情報を設定
 currentInstallation.favorite = currentLoginUser.favorite;
 // installation情報の更新
 currentInstallation.update()
     .then(function(installation) {
         // 更新に成功した場合の処理
         alert("お気に入り登録に成功");
         showShopDetail(currentShopId);
     })
     .catch(function(error) {
         // 更新に失敗した場合の処理
     });   
} else {
     // 更新に成功した場合の処理
     alert("お気に入り登録に成功");
     showShopDetail(currentShopId);
}                     
```


-----
## プッシュ通知を送信①セグメント配信
__動作確認⑤mBaaS準備__

* もう一度会員情報登録画面を表示するため、mBaaSの会員管理画面で「クラスの編集」をクリックします
* 「nickname」にチェックを入れて上の「削除」ボタンで削除します

-----
## プッシュ通知を送信①セグメント配信
__動作確認⑤mBaaS準備__

![favorite.png](https://qiita-image-store.s3.amazonaws.com/0/18698/a786c67e-3eea-99ce-96d8-6f43c534a6ef.png)



-----
## プッシュ通知を送信①セグメント配信
__動作確認⑥セグメント配信__

* 実機でアプリをビルドします
* アプリを起動します。
    * iOSの場合、「プッシュ通知」を許可（Yes）を選択ください

-----
## プッシュ通知を送信①セグメント配信
__動作確認⑥セグメント配信__
 
* mBaaSのダッシュボードでは端末が登録さていることを確認します。
![dashboardinstallation.png](https://qiita-image-store.s3.amazonaws.com/0/18698/2720e5d1-3e6d-f85b-ccae-a8e45e4cfa4d.png)
 

-----
## プッシュ通知を送信①セグメント配信

__動作確認⑥セグメント配信__

* 以下のユーザーに絞り込んでプッシュ通知を配信してみましょう
 * shopBをお気に入り登録しているユーザー
* 今回は登録ユーザーが１人(１端末)なので、shopBをお気に入りに設定しておいてください

-----
## プッシュ通知を送信①セグメント配信

__動作確認⑥セグメント配信__

* mBaaSのダッシュボードからShopクラスのデータを開きます
* shopBの「objectId」をコピーします

![動作確認⑥セグメント2.png](https://qiita-image-store.s3.amazonaws.com/0/112032/70eff815-e9e3-65d2-1603-bcc0628fc692.png)

-----
## プッシュ通知を送信①セグメント配信

__動作確認⑥セグメント配信__

* プッシュ通知を作成します
* メッセージを入力します
 * 例：ShopBセール開催中！

* 「iOS端末に配信する」にチェックを入れます
* 「配信端末」を設定します

![動作確認⑥セグメント1.png](https://qiita-image-store.s3.amazonaws.com/0/112032/bf4c5dbe-47aa-1f62-7526-d63730db7bdf.png)

-----
## プッシュ通知を送信①セグメント配信

__動作確認⑥セグメント配信__

* 「installationクラスからの絞込み」を選択します
* 絞り込み設定をします
 * ここでコピーしたShopBのobjectIdを貼り付けます

![動作確認⑥セグメント3.png](https://qiita-image-store.s3.amazonaws.com/0/112032/b227bd42-07c0-d294-b06d-612a0c0e6265.png)

-----
## プッシュ通知を送信①セグメント配信

__動作確認⑥セグメント配信__

* 「１端末に向けて送信されます」と表示されればOKです
* 「プッシュ通知を作成する」をクリックします
* 少し待つと配信されます→端末を確認！

![動作確認⑥セグメント4.png](https://qiita-image-store.s3.amazonaws.com/0/112032/9cab1a38-ae31-5169-cfdb-fdef4a6f3f38.png)

-----
## プッシュ通知を送信①セグメント配信

__動作確認⑥セグメント配信__

* いろいろなパターンで送ってみましょう！
 * 別のショップを絞り込み
 * 性別で絞込み
 * ShopAをお気に入り登録かつ女性で絞込み
 * ShopDをお気に入り登録かつ東京都で絞込み
 * etc...

-----
## プッシュ通知を送信②リッチプッシュ

__リッチプッシュについて__

* プッシュ通知登録時にURLを指定することで、開封時にWebビューを表示できる機能です
* プッシュ通知開封でアプリが起動するときに表示されます
 * アプリ起動中には表示されませんので閉じる必要があります（仕様）


-----
## プッシュ通知を送信②リッチプッシュ

__リッチプッシュについて__

* 今回はShopのセール画像を「公開ファイル」機能を利用して配信します

![sale](https://qiita-image-store.s3.amazonaws.com/0/112032/1487da6d-b4e4-4337-1b87-098781ea3f78.png)

-----
## プッシュ通知を送信②リッチプッシュ

__リッチプッシュについて__

* リンクは以下のように作成できます

```
https://mb.api.cloud.nifty.com/2013-09-01/applications/*****アプリケーションID*****/publicFiles/*****ファイル名*****
```

  * 「*****アプリケーションID*****」はアプリIDを指定します
  * 「*****ファイル名*****」はセール画像の名前を指定します

-----
## プッシュ通知を送信②リッチプッシュ

__リッチプッシュについて__

* ブラウザでリンクをたたいて確認してください！

![publicfile](https://qiita-image-store.s3.amazonaws.com/0/112032/6a02b418-c8f2-ad02-f9fd-7d8eb1d45673.png)

-----
## プッシュ通知を送信②リッチプッシュ

__動作確認⑦リッチプッシュ__

* 実機でアプリをビルドします
* アプリを一旦完全に閉じます
* プッシュ通知を作成します
* URL欄に作成した公開ファイルのURLを貼り付けます
* そのまま送信してみましょう

-----
## プッシュ通知を送信②リッチプッシュ

__動作確認⑦リッチプッシュ__

![push setting](https://qiita-image-store.s3.amazonaws.com/0/112032/430e4661-8627-a1a7-a82c-918f5dbf3aa3.png)


-----
## まとめ

__学んだこと__

* mBaaSの各機能を使用してアプリ作成方法を学んだ！
  * 会員管理機能・データストア・ファイルストア・プッシュ通知をマスター◎
* プッシュ通知の活用方法がわかった！
  * 絞り込み配信・リッチプッシュをマスター◎


-----
## 参考

* 開催中の[セミナー](http://mb.cloud.nifty.com/seminar.htm)のご案内
* ハンズオン内容が実装された完全版プロジェクト
  * [MonacaAdvancePush【完成版】](https://github.com/ncmbadmin/MonacaAdvancePush/archive/full_version.zip)
* コードはGitHubに公開しています
  * full_version：完成版
  * handson_version：セミナー版