# 使用 FCM 建立App推播服務 Web Push Notifications to App(Web篇)
大家好,我是app組曾經的某一位組長ヽ(✿゚▽゚)ノ,因緣際會下在一次的專案中寫了一點網頁的前後端以及FCM的相關功能,因此寫了一篇部落格來記錄,以下內容如有謬誤請不吝賜教_(:3 」∠ )_
前言:自從Google cloud Message(GCM)在2019被移除了之後,Firebase Cloud Messaging(FCM)成為了一種新的跨平台的消息傳遞解決方案。
[詳情可以去看firebase的官方文件](https://firebase.google.com/docs/cloud-messaging/fcm-architecture)
## FCM體系結構概述
- 註冊設備以接收來自FCM的消息 。客戶端應用程序的實例進行註冊以接收消息,從而獲得唯一標識該應用程序實例的註冊令牌。
- 發送和接收下游消息 。
- 發送消息。應用服務器將消息發送到客戶端應用:
1. 該消息是在Notifications作曲器或受信任的環境中編寫的,並且消息請求被發送到FCM後端。
2. FCM後端接收消息請求,生成消息ID和其他元數據,並將其發送到平台特定的傳輸層。
3. 當設備在線時,消息將通過平台特定的傳輸層發送到設備。
4. 在設備上,客戶端應用接收消息或通知。
- 總結自官方文件敘述

## 一、取得伺服器金鑰(API_ACCESS_KEY)
1. 進入firebase的專案頁面

2. 在左上角設定按鈕中找到“專案設定”

3. 進入"Cloud Messaging"頁面,找到你的伺服器金鑰,如果沒有變生成一個新的金鑰

## 二、發送推播(PHP)
```php
// send token to firebase server to push message
function send_notification($tokens, $title, $body, $nowTime)
{
$this->lib->AccessCheck("send notifications");
$url = 'https://fcm.googleapis.com/fcm/send';
//prep the bundle(set what you need in the JSON)
$fields = array(
'registration_ids' => $tokens,
'data' => array(
'data' => $nowTime
),
'notification' => array(
'title' => $title,
'body' => $body
)
);
$headers = array(
'Authorization:your API_ACCESS_KEY',
'Content-Type: application/json',
);
//Send Response To FireBase Server
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
//return Result Of FireBase Server
return $result;
}
```
## 三、推播結果
```php
/ get result message to http (status code)
private function push_notification($title, $body)
{
$this->lib->AccessCheck("send notifications");
$flag = true; //下一頁顯示的是 成功 或 失敗
$errorMsg = array();
//message[] 傳到view顯示的訊息
$message = array();
// 取得使用者資料
$result = $this->FCM_model->get_user_token();
if ($result == "false") { //uid不存在
$flag = false;
array_push($errorMsg, "群組不存在");
$message['success'] = -3;
}
if ($flag == true) {
// 要顯示在畫面上用的
$message['result'] = $result;
// 取得時間
$nowTime = date('Y-m-d h:i:s');
// 傳送推播
$message_status = $this->send_notification($this->get_tokens_from_result($result), $title, $body, $nowTime);
// 要顯示在畫面上用的
$message['fcm_status'] = $this->handle_FCMResult($message_status); //json to array
array_push($errorMsg, "成功");
$message['success'] = '成功';
}
return $message;
// 顯示 換頁
}
```