# go-fcm-example **Repository Path**: ntf2gd_7/go-fcm-example ## Basic Information - **Project Name**: go-fcm-example - **Description**: No description available - **Primary Language**: Java - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-07-14 - **Last Updated**: 2024-07-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 编写目的 FCM官方文档中描述比较零散,我自己在调研接入方式时也耗费了一些时间,所以我想编写一个文档,对接入FCM前后端的改造点做一个完整的描述,也算是对FCM调研过程做一个总结,希望能给有相关需求的人一些参考,文档会分为FCM服务申请,WEB端SDK接入,服务器端消息发送三个部分来描述 # 参考资料 [FCM官方文档](https://firebase.google.com/docs/cloud-messaging) ## 一、FCM服务申请 谷歌推送以前叫GCM,在2019年4月11日迁移到了firebase cloud message(FCM),我们要使用FCM,需要在firebase上创建一个项目,所以需要有一个gmail邮箱 ### 1.1 添加项目 访问[https://console.firebase.google.com/](https://console.firebase.google.com/),登陆后可以看到以下界面: ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/create.png) 然后点击Add project,创建一个firebase项目 ### 1.2 获取应用凭证 创建号项目之后,点击项目→进入控制台 → 点击设置 ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/setting.png) 然后在常规信息栏中,查看到web应用凭证,这里也提供了npm和cdn的集成方式示例 ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/config.png) 应用凭证是用来给到前端集成SDK与FCM创建长链接,这里我们这里的应用凭证是: ``` javascript { apiKey: "AIzaSyAUVTaipaExXUTGGc7e-A3gUiA3Q8i7O8Y", authDomain: "shipment-portal-1f1b3.firebaseapp.com", projectId: "shipment-portal-1f1b3", storageBucket: "shipment-portal-1f1b3.appspot.com", messagingSenderId: "333922912996", appId: "1:333922912996:web:18467f5642e6fba00efaf1", measurementId: "G-5HNY007WZW" } ``` 然后在回到云消息传递信息栏,查看到服务器密钥 ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/serverkey.png) 服务器密钥用来向FCM推送消息,然后由FCM通过长链接推送给web客户端 服务器密钥用来可以添加多个,这里我们使用的密钥是: ``` AAAAjaT6Kls:APA91bFki15CULQgVFGKn1N3cR-PlKhcU5wMEClTl5NtP9YQylHSBsJctlZzQ0sdp6TnOsp5jyzzqW4tzSVDneKCmP8XQ8ZgA8w6wk6AW28aAdZn6eyz0U-OA7TuJ2WlkBbS10KcxQHe ``` ## 二、前端项目集成firebase sdk 前端可以通过npm或cdn的方式将fcm集成进自己的web项目,这里我用cdn的方式做示例,npm的操作方式可以参考:https://firebase.google.com/docs/web/setup ### 2.1 创建index.html 在界面上我们添加了一个accountId的输入框,点击登录之后,会将accountId和当前web客户端的token发送给服务器,用来模拟用户登陆的场景,界面如下: ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/front.png) 在onload中我们初始化firebase,并通过requestPermission方法请求用户允许发送通知,然后注册了一个messaging.onMessage监听,当FCM通过长链接推送消息到web客户端时,并且web应用位于前台时,会执行onMessage方法,请求用户允许通知界面如下: ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/allow.png) index.html的所有代码如下: ```

FCM

account:
0
``` ### 2.2 创建firebase-messaging-sw.js 当用户界面处于后台时,是无法触发onMessage方法,firebasebase基于service work提供了onBackgroundMessage方法,我们在index.html同目录下创建一个firebase-messaging-sw.js,然后注册一个onBackgroundMessage方法 代码如下: ``` importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js'); // Initialize the Firebase app in the service worker by passing in the // messagingSenderId. firebase.initializeApp({ apiKey: "AIzaSyAUVTaipaExXUTGGc7e-A3gUiA3Q8i7O8Y", authDomain: "shipment-portal-1f1b3.firebaseapp.com", projectId: "shipment-portal-1f1b3", storageBucket: "shipment-portal-1f1b3.appspot.com", messagingSenderId: "333922912996", appId: "1:333922912996:web:18467f5642e6fba00efaf1", measurementId: "G-5HNY007WZW" }); // Retrieve an instance of Firebase Messaging so that it can handle background // messages. const messaging = firebase.messaging(); messaging.onBackgroundMessage((payload) => { console.log('Received background message ', payload); // console.log(self) var title = payload.data.title var options = { body: payload.data.body, icon: payload.data.url } self.registration.showNotification(title, options); }); ``` 我们在onBackgroundMessage中通过showNotification弹出一个弹框,当web应用处于后台时(用户未停留在web界面),有FCM传递过来的新消息,会弹出一个弹框,效果如下: ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/backnotice.png) ## 三、后端项目发送通知消息 ### 3.1 交互流程图 ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/fcmflow.png) ### 3.2 创建Admin项目 创建一个Admin项目模拟我们的后台,主要是提供了查询在线用户列表,登陆,发送消息三个基本功能,用来模拟和web端的交互,admin的界面如下: ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/admin.png) * 查询在线用户列表:用户初始化SDK成功之后,我们需要将用户的accountId和当前的token保存起来; * 登陆:在用户web界面,点击login之后会将accountId和token传递给后台进行保存; * 发送消息:输入需要发送的accountId和title body,url之后,点击send,消息内容达到后台之后,会通过POST请求发给FCM; ## 四、总结 ### 4.1 项目代码: ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/project.png) ### 4.2 后端启动 后端是基于gin构建,直接启动main函数即可启动 ### 4.3 前端启动 静态资源的部署有很多种方式,一般我们可以利用nginx去部署,这里我们利用http-server这种更加轻量的方式启动一个http-server服务器,http-server是一个轻量级的基于nodejs的http服务器,可以使任意一个目录成为服务器的目录,完全抛开后台的沉重工程,直接运行想要的js代码。 #### 4.2.1 安装node 直接下载安装即可,官网地址: https://nodejs.org 安装成功之后在命令行输入命令$ node -v以及$ npm -v检查版本,确认是否安装成功。 #### 4.2.2 安装http-server 打开终端输入: ```npm install http-server -g``` 安装成功之后进入目标文件夹,这里就是我们项目的 front/src 然后输入: ```http-server``` 这样就会在本地8080端口启动一个http服务器(如果8080被占用则会在8081端口启动,以此类推),启动界面如下: ![avatar](https://raw.githubusercontent.com/caixunshi/go-fcm-example/main/doc/img/http-server.png) 用户web界面为:[http://localhost:8080/index.html](http://localhost:8080/index.html) 后端管理界面为:[http://localhost:8080/admin.html](http://localhost:8080/admin.html) 这样我们就可以在两个浏览器分别测试消息发送啦 PS: 用户web界面谷歌浏览器service work不支持非https,所以不能测试用户离开web界面的弹框提醒场景,只能测试用户停留在web界面接受消息的场景,需要看效果的可以用firefox ### 4.3 思考 * 用户初始化SDK并与FCM建立长链接是没有传入业务参数的,生成出来的token是跟我们的业务数据(如用户)无关的,所以我们需要客户端主动上报token 和 username,并在我们自己的后台维护这个关系,但这也衍生出来几个问题,需要根据具体的业务场景去制定解决方案。 * 用户在多个端(比如多个浏览器)登陆时,一个用户会有多个token,如果想要所有端都通知的话,就需要保留所有的token,否则就只有最后登陆的端能接收到消,用户量很大的情况下,保存这个关系需要成本; 用户下线之后,服务器的token和user的关联关系如何删除?(直接关掉web界面或直接kill 掉 app);