Firebase推送通知服务端实现

Firebase控制台配置

Firebase后台创建项目,获取相关参数和配置如下

(1)点击Project Overview -> 项目设置 -> 云消息传递 中获取服务器密钥(建议,当然旧版服务器密钥也可以使用)

(2)服务账号 -> 点击生成新的私钥,获取私钥配置(json文件,丢失后可以重新生成,重新生成后需要替换旧的配置)

(3)Database -> 以测试模式创建数据库 -> 选择 Realtime Database 获得数据库url

发送推送通知

参考:https://fcm.googleapis.com/fcm/send

要发送消息,应用服务器需发出POST请求。例如:

请求地址:https://fcm.googleapis.com/fcm/send

HTTP请求头必须包含:

Authorization: key=YOUR_SERVER_KEY
Content-Type: application/json 或 application/x-www-form-urlencoded;charset=UTF-8(纯文本格式)。如果省略Content-Type,即视为纯文本格式

HTTP 正文内容取决于您使用的是 JSON 还是纯文本。有关 JSON 或纯文本消息中可能包含的所有参数列表,请参阅服务器参考。
https://firebase.google.com/docs/cloud-messaging/http-server-ref?hl=zh-cn#params

(1) 可以使用to单个推送,也可以使用registration_ids批量发送,但是做多1000个token
(2) 给多个人推,有两种:一种是给组推,一种是给主题推

Node.js实现

# node install firebase
# node install request
# node fcm.js
var firebase = require('firebase');
var request = require('request');

var API_KEY = 'AAAA8mBttg8:APA91bFv9xob7x7-lBRqDwYdd1IbR5DcqUUmQE8t_cWKJSA5WjNbbp0jOWpCCHnarD2JV3MGyqEM3DfQGd8Kvt5swlGJlGqRoPGFPaSrNn44ZzLLz-HotPRzd08koeJf5bshdPzxKoq1';

var token = 'chPUpTJMeS8:APA91bGlo27OQVskyiqlXvDQGulrIFi9iIpowsjsrKe-0k5rilbjfB3WADSzujtZH3u-HEPcNMZiHZd7j8-CpXauLY39-u8m9kllLxOOo9Ja1LFAtmSB3vXKhiJAwQC31BlhSqILvSqb';

firebase.initializeApp({
    serviceAccount: "pandadeal-firebase-push.json",
    databaseURL: "https://panda-deal-ios.firebaseio.com/"
});

var payload = {
    //to: token,
    to: '/topics/activity',
    notification: {
        body: "通知内容",
        title: "Firebase Cloud Message",
        data: {'type': 'test', 'path': '/home'}
    }
}

setTimeout(function (args) {
    sendNotificationToUser(payload);
}, 200);

function sendNotificationToUser(message, onSuccess) {
    request({
        url: 'https://fcm.googleapis.com/fcm/send',
        method: 'POST',
        headers: {
            'Content-Type' : 'application/json',
            'Authorization': 'key=' + API_KEY
        },
        body: JSON.stringify(message)
    }, function(error, response, body) {
        if (error) {
            console.log('---message send error---', error);
        }
        else if (response.statusCode >= 400) {
            console.log('HTTP Error: ' + response.statusCode + ' - ' + response.statusMessage);
        }
        else {
            console.log(body)
            console.log('---message send success---')
            onSuccess && onSuccess();
        }
    });
}

Java实现

public class TestFireBase {

    public final static String AUTH_KEY_FCM= ""; //App服务密钥

    public final static String API_URL_FCM = "https://fcm.googleapis.com/fcm/send"; //谷歌推送地址

    public static void main(String[] args) {
        pushFCMNotification();
    }

    public static void pushFCMNotification() {
        try {
            URL url = new URL(API_URL_FCM);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setUseCaches(false);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");    
            conn.setRequestProperty("Authorization", "key="+AUTH_KEY_FCM);
            conn.setRequestProperty("Content-Type", "application/json"); //不设置默认发送文本格式
            JSONObject json = new JSONObject();
            json.put("to", "App Token"); //单一推送
            //json.put("registration_ids", tokens); //批量推送,最多1000个token,此处的tokens是一个token JSONArray数组
            JSONObject info = new JSONObject();
            info.put("title", "Notification Tilte");
            info.put("body", "Hello Test Notification");
            info.put("icon", "myicon");
            json.put("notification", info); //json还可以put其他参数

            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
            wr.write(json.toString());
            wr.flush();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = null;
            while ((line = reader.readLine())!= null) {
                System.out.println(line);
            }
            wr.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

PHP实现

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

use cn\appblog\fcm\Client;
use cn\appblog\fcm\Message;
use cn\appblog\fcm\Recipient\Device;
use cn\appblog\fcm\Notification;

class FcmController extends Controller {

    private $apikey;
    public function __construct()
    {
        $this->apikey = 'API_KEY';
    }

    //用Fcm推送消息
    public function push($content='', $fcmtoken='')
    {
        $apiKey = $this->apikey;
        $client = new Client();
        $client->setApiKey($apiKey);
        $client->injectHttpClient(new \GuzzleHttp\Client());

        //$note = new Notification('test title', '现在时间是 '.date('Y-m-d H:i:s'));
        $note = new Notification('', $content);
        $note->setIcon('smile')
            ->setColor('#ffffff')
            ->setBadge(1);

        $message = new Message();
        $message->addRecipient(new Device($fcmtoken));
        $message->setNotification($note)
            ->setData(array('someId' => 11112));
        $message->setNotification($note);

        $response = $client->send($message);
        var_dump($response->getStatusCode());
    }

    /**
     * @param array $requestData
     * @return bool
     */
    public function old_insertIntoGroup($requestData=[])
    {
        if(!$requestData['tuid'] || !$requestData['version'] || !$requestData['fcmtoken']) {
            return false;
        }

        //创建和添加设备组的url
        $url = 'https://android.googleapis.com/gcm/notification';

        $header = [
            'Content-Type:application/json',
            'Authorization:key = '.$this->apikey,
            'project_id: 项目id',
        ];
        $groupkey = '';
        //先查找表中最近新的设备组的key,若key里面的子账号已经达到一定数目,就新建一个组
        $gdata=DB::select('select count(id) num,groupkey from zeai_andro_push group by groupkey order by id desc limit 1;');
        //$gdata=DB::select('select groupkey from zeai_andro_push order by id desc limit 1;');

        //确保能有推送fcmtoken
        if(!DB::table('zeai_andro_push')->where(['tuid'=>$requestData['tuid']])->count(['id'])) {
            $requestData['groupkey'] = $gdata[0]->groupkey;
            DB::table('zeai_andro_push')->insertGetId($requestData);
        }
        $groupkey=$gdata[0]->groupkey;
        $data = [
            "operation"=>"add",
            "notification_key_name"=> "appUser-Chris", //设备组名
            "notification_key"=>$groupkey,
            "registration_ids"=>[$requestData['fcmtoken']]
        ];

        $res = json_decode($this->http($url, $data, 'post', $header), true);
        if (isset($res['notification_key'])) {
            $res=DB::table('zeai_andro_push')
                ->where(['tuid'=>$requestData['tuid']])
                ->update([
                    'groupkey'=>$res['notification_key']
                ]);
            return  $res ? true : false;
        } else {
            //一个设备组是否满员未能测试
            return false;
        }
    }

    /**
     * 添加用户的主题,保存用户的fcmtoken
     * @param array $requestData
     * @return bool
     */
    public function insertIntoGroup($requestData=[])
    {
        if (!$requestData['tuid'] || !$requestData['version'] || !$requestData['fcmtoken']) {
            return false;
        }
        $this->oldmyTopic($requestData['fcmtoken']);
        //先查找表中最近新的设备组的key,若key里面的子账号已经达到一定数目,就新建一个组

        //确保能有推送fcmtoken
        if (!DB::table('zeai_andro_push')->where(['tuid'=>$requestData['tuid']])->count(['id'])) {
            $requestData['groupkey'] = 0;
            DB::table('zeai_andro_push')->insertGetId($requestData);
        }
    }

    //创建设备组
    public function createGroup($fcmtoken='')
    {
        //创建和添加设备组的 url
        $url = 'https://android.googleapis.com/gcm/notification';
        $header = [
            'Content-Type:application/json',
            'Authorization:key='.$this->apikey,
            'project_id:196236249110',
        ];
        $data = [
            "operation"=>"create",
            "notification_key_name"=> (string)time(),//设备组名
            "registration_ids"=>[$fcmtoken]
        ];
        $res = json_decode( $this->http($url, $data, 'post', $header), true);
        return $res['notification_key'];
    }

    //向主题发送消息
    public function sendMessageToGroup()
    {
        $url = 'https://fcm.googleapis.com/fcm/send';
        $header = [
            'Content-Type:application/json',
            'Authorization:key='.$this->apikey,
            'project_id:196236249110',
        ];
        $data = [
            'to'=>'/topics/主题名',
            "notification"=>[
                'body'=>"^_^ Come and get the coins.There are a lot of new tasks. ^_^",
                'title'=>'',
                'icon'=>'myicon'
            ],
        ];
        $res = $this->http($url,$data,'post',$header);
        var_dump($res);
    }

    /**
     * 获取自己的主题内容
     */
    private function myTopic($fcmtoken='')
    {
        $url='https://iid.googleapis.com/iid/info/'.$fcmtoken.'?details=true';
        $header = [
            //'Content-Type:application/json',
            'Authorization:key='.$this->apikey,
            'details:true',
        ];
        $res=$this->http($url, '', 'get', $header);
        var_dump($res);
    }

    /**
     * 给自己添加主题 wdwdinstagram
     * @param $fcmtoken
     */
    private function oldmyTopic($fcmtoken)
    {
        $url='https://iid.googleapis.com/iid/v1/'.$fcmtoken.'/rel/topics/主题名';
        $header = [
            'Content-Type:application/json',
            'Authorization:key='.$this->apikey,
            'Content-Length: 0',
        ];
        $this->http($url, '', 'post', $header);
    }
}

注:需翻墙,否则报错SERVICE_NOT_AVAILABLE

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/04/01/implementation-of-firebase-push-notification-server/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Firebase推送通知服务端实现
Firebase控制台配置 Firebase后台创建项目,获取相关参数和配置如下 (1)点击Project Overview -> 项目设置 -> 云消息传递 中获取服务器密钥(建议,当……
<<上一篇
下一篇>>
文章目录
关闭
目 录