本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:Firebase 消息服务(基于 Firebase Cloud Messaging)支持 Android、iOS 和 Web 应用的实时消息推送,提升用户参与度和交互体验。本教程围绕“已发送 Firebase 消息”这一状态展开,详细讲解 Firebase 消息服务的配置与实现流程,涵盖项目设置、SDK 集成、设备令牌获取、消息构建与发送、客户端消息处理等关键环节。适合希望掌握推送通知开发的移动与 Web 开发者。
Firebase-Message:已发送 Firebase 消息

1. Firebase 消息服务介绍

Firebase Cloud Messaging(FCM)是 Google 提供的跨平台消息推送服务,支持 Android、iOS 和 Web 应用。它允许开发者通过云服务向客户端发送通知和数据消息,实现实时通信。

1.1 核心功能概述

FCM 提供多种消息类型,包括:

  • 通知消息(Notification Messages) :预定义格式的消息,用于在客户端弹出通知。
  • 数据消息(Data Messages) :开发者自定义的数据结构,适用于后台处理逻辑。
  • 后台消息处理(Background Message Handling) :即使应用未处于前台,也能通过 Service Worker 接收并处理消息。

1.1.1 消息类型的使用示例(Web 端):

// 接收 FCM 数据消息示例
messaging.onMessage((payload) => {
  console.log('Message received. ', payload);
  // 处理数据消息逻辑
});

参数说明:
- payload :接收到的消息对象,包含 data notification 字段,取决于消息类型。

1.1.2 应用场景分析

FCM 的典型应用场景包括:

应用场景 描述
用户唤醒 通过通知唤醒用户,如订单状态更新
实时通信 消息推送用于聊天应用或社交通知
后台同步 推送指令触发客户端数据同步或更新

1.2 FCM 的优势分析

相较于其他推送服务(如 Apple APNs、第三方推送平台),FCM 具备以下优势:

  • 跨平台支持 :统一管理 Android、iOS、Web 的消息推送。
  • 集成成本低 :与 Firebase 生态无缝集成,便于构建完整后端服务。
  • 可扩展性强 :支持大规模设备推送、多播、主题订阅等高级功能。
  • 安全性高 :支持密钥认证、HTTPS 传输,保障消息通道安全。

例如,使用 Firebase Admin SDK 或 REST API,开发者可轻松构建后端服务实现消息下发。

下一章将详细介绍如何创建和配置 Firebase 项目,为后续集成做好准备。

2. Firebase 项目创建与配置

在使用 Firebase Cloud Messaging(FCM)进行消息推送之前,首要任务是创建一个 Firebase 项目并完成基础配置。这一过程不仅涉及项目创建、应用添加、配置文件获取等基本操作,还包括安全权限的设置以及消息服务相关密钥的配置。本章将从 Firebase 控制台的入门操作开始,逐步深入到 Web 应用接入、项目配置、消息服务启用及密钥管理等关键步骤,帮助开发者系统性地完成 Firebase 项目的构建与配置。

2.1 Firebase 控制台入门

Firebase 提供了直观的 Web 控制台,开发者可以通过 Google 账号轻松登录并管理项目。控制台是 Firebase 所有功能的入口,包括项目创建、应用管理、服务配置等。对于新用户来说,熟悉 Firebase 控制台的使用是入门的第一步。

2.1.1 注册 Google 账号并登录 Firebase 控制台

要使用 Firebase,首先需要拥有一个有效的 Google 账号。Google 账号可以是个人 Gmail 账号、Google Workspace 账号或组织账号。访问 Firebase 官方网站 并点击“Go to Console”按钮,系统将跳转至 Google 登录页面。

graph TD
    A[访问 Firebase 官网] --> B[点击 Go to Console]
    B --> C[跳转至 Google 登录页面]
    C --> D[输入 Google 账号]
    D --> E[登录 Firebase 控制台]

成功登录后,用户将进入 Firebase 控制台首页,可以看到所有已创建的项目,也可以创建新项目。

2.1.2 创建新项目与项目命名规范

在 Firebase 控制台首页点击“Add project”按钮,即可开始创建新项目。创建流程包括以下几个关键步骤:

  1. 输入项目名称 :项目名称应具有业务相关性,便于识别,例如 myapp-notification
  2. 选择 Google Cloud 组织(可选) :如果是企业用户,可以选择组织来统一管理多个项目。
  3. 选择项目 ID :系统自动生成一个唯一 ID,也可自定义。该 ID 将用于 Firebase 资源标识,例如数据库、存储等。
  4. 同意服务条款 :确认 Firebase 使用条款后,点击“Create Project”。
步骤 操作内容 说明
1 输入项目名称 推荐使用业务相关名称
2 选择组织 适用于企业用户
3 设置项目 ID 系统自动生成或自定义
4 同意条款 必须勾选才能继续

创建完成后,系统会跳转至项目主页,开发者可以在此页面进行后续配置操作。

2.2 项目设置与基础配置

完成项目创建后,下一步是将应用接入 Firebase。本节以 Web 应用为例,讲解如何添加 Web 应用、获取配置文件(firebaseConfig)以及设置项目的安全与权限。

2.2.1 添加 Web 应用到 Firebase 项目

进入 Firebase 控制台的项目主页,点击“Web”图标(),然后点击“Add app”按钮。系统将引导你完成 Web 应用的添加流程:

  1. 输入应用昵称(App nickname),例如 mywebapp
  2. 选择是否启用 Firebase Hosting(可选)。
  3. 点击“Register app”,完成注册。
graph TD
    F[项目主页] --> G[点击 Web 应用图标]
    G --> H[点击 Add app]
    H --> I[输入应用昵称]
    I --> J[是否启用 Hosting]
    J --> K[点击 Register app]

注册完成后,系统会生成一段 JavaScript 初始化代码,包含 firebaseConfig 配置对象。

2.2.2 获取配置文件(firebaseConfig)

在注册 Web 应用的最后一步,Firebase 会显示如下代码段:

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "your-project-id.firebaseapp.com",
  projectId: "your-project-id",
  storageBucket: "your-project-id.appspot.com",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID"
};

// Initialize Firebase
const app = firebase.initializeApp(firebaseConfig);

逻辑分析
- apiKey :用于访问 Firebase API 的密钥,具有一定的安全性要求。
- authDomain :用于 Firebase Authentication 的域名。
- projectId :项目唯一标识。
- storageBucket :用于 Firebase Storage 的存储桶地址。
- messagingSenderId :用于 FCM 消息发送的唯一标识。
- appId :应用唯一 ID,用于区分不同应用。

这段代码应嵌入到 Web 应用的 HTML 页面中,并确保在加载 Firebase SDK 后立即初始化。

2.2.3 项目设置中的安全与权限管理

在 Firebase 控制台的“Project settings”中,开发者可以管理项目成员、API 密钥、服务账号等。安全与权限管理主要包括以下几个方面:

  1. 成员管理 :添加团队成员并分配角色(如 Viewer、Editor、Owner)。
  2. 服务账号(Service Accounts) :用于服务器端与 Firebase 的交互,例如使用 Admin SDK 发送消息。
  3. API 密钥管理 :查看或限制 API 密钥的使用范围,防止滥用。
类别 内容 说明
成员管理 添加/删除成员、设置角色 控制项目访问权限
服务账号 查看服务账号、生成密钥 用于后端与 Firebase 通信
API 密钥 管理 API 密钥的使用权限 防止密钥泄露或滥用

建议将 API 密钥限制为特定用途(如仅限 FCM),并定期轮换密钥以增强安全性。

2.3 消息服务启用与密钥配置

FCM 是 Firebase 提供的消息推送服务,必须在项目中启用并配置相关密钥才能发送消息。

2.3.1 启用 Firebase Cloud Messaging API

在 Firebase 控制台中,点击左侧导航栏的“Cloud Messaging”选项,进入 FCM 设置页面。首次访问时,系统会提示启用 Cloud Messaging API。点击“Enable”按钮即可完成启用。

graph TD
    L[控制台主页] --> M[点击 Cloud Messaging]
    M --> N[提示启用 API]
    N --> O[点击 Enable 按钮]

启用后,开发者可以在此页面查看 FCM 的使用统计、设备注册情况以及测试消息发送功能。

2.3.2 获取服务器密钥与发送权限配置

在 FCM 设置页面中,点击“Project settings” > “Cloud Messaging”标签页,可以看到“Server key”和“Sender ID”。

  • Server key :用于后端服务器调用 FCM REST API 或 Admin SDK 发送消息时的身份验证。
  • Sender ID :用于客户端注册设备令牌(Token)时的身份识别。

⚠️ 安全提示 Server key 具有较高的权限,应妥善保管,避免泄露。建议通过环境变量或配置文件方式存储,避免硬编码在代码中。

以下是一个使用 Node.js 发送 FCM 消息的示例代码(需配合 Admin SDK):

const admin = require('firebase-admin');

const serviceAccount = require('./path/to/serviceAccountKey.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'https://your-project-id.firebaseio.com'
});

const message = {
  token: 'device_token_here',
  notification: {
    title: 'Hello',
    body: 'This is a test message.'
  }
};

admin.messaging().send(message)
  .then((response) => {
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

代码分析
- admin.initializeApp() :初始化 Firebase Admin SDK,使用服务账号密钥进行认证。
- admin.messaging().send() :发送 FCM 消息,支持通知消息与数据消息。
- token :目标设备的注册令牌。
- notification :通知消息体,包含标题和内容。

2.3.3 项目设置中常见问题与排查

在项目配置过程中,开发者可能会遇到以下常见问题:

问题类型 原因 解决方案
Firebase 初始化失败 firebaseConfig 配置错误 检查 apiKey projectId 等字段是否正确
无法获取 Token 未启用 FCM 或浏览器权限未允许 检查是否启用 FCM 并请求用户推送权限
发送消息失败 Server key 错误或 Token 无效 检查密钥权限、Token 有效性及网络连接

此外,建议使用 Firebase 控制台的“Test your notification”功能进行快速测试,验证消息是否能够成功发送。

通过本章的详细讲解,开发者应能够熟练掌握 Firebase 项目的创建、Web 应用接入、配置文件获取、FCM 启用及密钥管理等关键步骤。这些配置为后续的 FCM 消息推送打下了坚实的基础。在下一章中,我们将深入探讨 Firebase SDK 在 Web 端的集成方式。

3. Firebase SDK 集成(Web 端)

在完成 Firebase 项目创建与基础配置之后,下一步是将 Firebase SDK 集成到 Web 应用中,以便实现 Firebase Cloud Messaging(FCM)的推送功能。本章将详细介绍如何在 Web 端引入 Firebase SDK、初始化 messaging 模块、处理推送权限申请、注册 Service Worker,并讨论 SDK 集成过程中可能遇到的常见问题及解决方案。

3.1 环境准备与依赖引入

在 Web 应用中集成 Firebase SDK,需要准备好开发环境并正确引入所需的依赖文件。

3.1.1 HTML 页面结构与脚本引入方式

要使用 Firebase SDK 的消息推送功能,首先需要在 HTML 页面中引入 Firebase 的核心库和 Messaging 模块。通常有两种方式引入:通过 CDN 或使用模块打包工具(如 Webpack、Vite)进行模块化引入。

通过 CDN 引入示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Firebase Web Push</title>
</head>
<body>
  <h1>Firebase Web Push 示例</h1>

  <!-- Firebase SDK 核心库 -->
  <script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js"></script>
  <!-- Firebase Messaging 模块 -->
  <script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-messaging-compat.js"></script>

  <!-- 自定义脚本 -->
  <script src="app.js"></script>
</body>
</html>

代码逻辑说明:
- firebase-app-compat.js 是 Firebase 的核心模块,用于初始化 Firebase 应用。
- firebase-messaging-compat.js 是兼容性版本的 Messaging 模块,适用于 Web 端。
- app.js 是开发者自定义的脚本文件,用于编写 Firebase 初始化和消息处理逻辑。

3.1.2 初始化 Firebase SDK 并配置 messaging 模块

接下来,需要在 app.js 中初始化 Firebase,并配置 Messaging 模块。你需要从 Firebase 控制台获取项目的 firebaseConfig 配置信息。

// app.js

// Firebase 配置对象(从 Firebase 控制台获取)
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_PROJECT_ID.appspot.com",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID",
  measurementId: "YOUR_MEASUREMENT_ID"
};

// 初始化 Firebase
firebase.initializeApp(firebaseConfig);

// 获取 Messaging 实例
const messaging = firebase.messaging();

// 请求推送权限
messaging.requestPermission()
  .then(() => {
    console.log('用户已授权推送权限');
    return messaging.getToken();
  })
  .then(token => {
    console.log('设备令牌:', token);
  })
  .catch(err => {
    console.log('请求权限失败:', err);
  });

参数说明:
- apiKey :用于识别项目身份的 API 密钥。
- projectId :Firebase 项目的唯一标识符。
- messagingSenderId :用于识别发送方的 ID,用于 FCM 推送。
- appId :Firebase 为应用分配的唯一 ID。
- getToken() :用于获取设备的注册令牌(Token),该 Token 是向该设备发送消息的关键。

逻辑分析:
1. 使用 firebase.initializeApp() 初始化 Firebase。
2. 调用 firebase.messaging() 获取 Messaging 实例。
3. 使用 messaging.requestPermission() 请求用户授权推送权限。
4. 成功授权后调用 messaging.getToken() 获取设备 Token。

3.2 Web 推送权限申请与服务工作线程

在 Web 端使用 FCM 推送,必须先获得用户的推送权限,并注册 Service Worker 以处理后台消息。

3.2.1 请求用户推送权限(Notification.requestPermission)

Web Push 需要用户明确授权才能接收通知。使用 Notification.requestPermission() 方法请求权限。

// app.js

if ('Notification' in window) {
  Notification.requestPermission().then(permission => {
    if (permission === 'granted') {
      console.log('用户允许推送通知');
    } else {
      console.log('用户拒绝推送通知');
    }
  });
}

逻辑分析:
- 首先检查浏览器是否支持 Notification API。
- 调用 requestPermission() 方法,弹出权限请求对话框。
- 用户点击允许后,返回 granted ;否则返回 denied default

3.2.2 注册 Service Worker 并处理后台消息

Service Worker 是 Web Push 的核心组件,负责接收和显示通知。必须在页面中注册 Service Worker 并监听 background message 事件。

注册 Service Worker:

// app.js

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/firebase-messaging-sw.js')
    .then(registration => {
      console.log('Service Worker 注册成功:', registration.scope);
    })
    .catch(error => {
      console.log('Service Worker 注册失败:', error);
    });
}

创建 firebase-messaging-sw.js 文件:

// firebase-messaging-sw.js

importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-messaging-compat.js');

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_PROJECT_ID.appspot.com",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID"
};

firebase.initializeApp(firebaseConfig);

const messaging = firebase.messaging();

// 监听后台消息
messaging.onBackgroundMessage(payload => {
  console.log('收到后台消息:', payload);

  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
    icon: '/icon.png'
  };

  self.registration.showNotification(notificationTitle, notificationOptions);
});

逻辑分析:
- 使用 importScripts() 引入 Firebase SDK。
- 初始化 Firebase,并获取 Messaging 实例。
- 监听 onBackgroundMessage 事件,当应用在后台时接收消息。
- 使用 showNotification() 显示通知。

3.3 SDK 集成中的常见问题与解决方案

在 Web 端集成 Firebase SDK 的过程中,可能会遇到跨域、HTTPS 要求、浏览器兼容性等问题。

3.3.1 跨域问题与 HTTPS 环境要求

HTTPS 要求

FCM 在 Web 端要求应用必须部署在 HTTPS 环境下。否则会报错: messaging/unsupported-browser Permission denied

解决方案:
- 使用本地开发服务器(如 http-server webpack-dev-server )时启用 HTTPS。
- 部署至支持 HTTPS 的服务器(如 GitHub Pages、Firebase Hosting)。

跨域问题(CORS)

如果在跨域环境下加载 Firebase SDK 或请求 Token,可能会遇到跨域限制。

解决方案:
- 确保所有请求都使用相同的域名。
- 使用代理服务器解决跨域问题。
- 检查 Firebase 控制台中是否已添加当前域名到授权域名列表。

3.3.2 浏览器兼容性与推送支持检测

不同浏览器对 Web Push 的支持程度不同,需进行兼容性检测。

兼容性检测示例:

if (!('PushManager' in window)) {
  console.log('当前浏览器不支持 Push API');
} else if (!('serviceWorker' in navigator)) {
  console.log('当前浏览器不支持 Service Worker');
} else if (!('Notification' in window)) {
  console.log('当前浏览器不支持 Notification API');
} else {
  console.log('当前浏览器支持 Web Push');
}
浏览器 Web Push 支持 HTTPS 要求 备注
Chrome ✅ 支持 ✅ 必须 HTTPS 支持良好
Firefox ✅ 支持 ✅ 必须 HTTPS 支持良好
Safari ✅ 支持(仅 macOS/iOS) ✅ 必须 HTTPS 仅支持 APNs
Edge ✅ 支持 ✅ 必须 HTTPS 基于 Chromium
iOS Safari ⚠️ 有限支持 ✅ 必须 HTTPS 依赖 APNs

注意事项:
- Safari 使用 Apple Push Notification service(APNs)而非 FCM。
- iOS 上的 Web Push 支持受限,建议使用原生推送替代。

小结

本章详细介绍了 Firebase SDK 在 Web 端的集成流程,包括:
- 引入 Firebase SDK 的方式;
- 初始化 Firebase 应用和 Messaging 模块;
- 请求推送权限并注册 Service Worker;
- 处理后台消息;
- 常见问题如 HTTPS 要求、跨域限制、浏览器兼容性等的解决方案。

后续章节将进一步介绍如何获取和管理设备 Token,以及如何构建和发送 FCM 消息。

4. FCM 设备令牌获取

在 Firebase Cloud Messaging(FCM)的消息推送体系中, 设备令牌(Token) 是实现消息精准投递的核心机制。它是设备与 Firebase 服务之间的唯一标识,是构建推送消息时必须依赖的关键信息。本章将深入解析设备令牌的生成原理、获取方式、刷新机制以及其在实际应用中的管理策略,帮助开发者全面掌握 Token 的生命周期管理,确保推送服务的稳定与安全。

4.1 设备令牌(Token)的概念与作用

在 Web 端和移动端的推送系统中,每一个设备都需要一个唯一的标识符来接收消息。这个标识符就是我们所说的“设备令牌”(Device Token),在 FCM 中称为 Registration Token

4.1.1 Token 的生成机制与唯一性

当用户首次访问 Web 应用并授权接收通知时,浏览器会与 Firebase 服务通信,生成一个唯一的 Token。该 Token 是由 Firebase 服务器动态生成的字符串,通常为 150~200 字符的 Base64 编码字符串。

Token 的生成遵循以下原则:

  • 唯一性 :每个设备和浏览器组合生成的 Token 是唯一的。
  • 动态性 :Token 可能会因用户清除缓存、更换设备、重新授权通知等原因而变化。
  • 绑定性 :Token 与 Firebase 项目中的应用(Web 或 App)绑定,不能跨项目使用。

以下是一个典型的 FCM Token 示例:

fcm_token_example: "fcm_token_abc123xyz789"

⚠️ 注意 :Token 是敏感信息,不应暴露在客户端或日志中,需在后端安全存储。

4.1.2 Token 在消息发送中的关键作用

Token 是 FCM 消息投递的核心参数,消息发送时必须指定目标设备的 Token。以下是其主要用途:

用途 说明
精准推送 通过指定 Token,消息可发送到特定设备
用户绑定 后端将 Token 与用户 ID 关联,用于个性化推送
设备管理 Token 可用于统计活跃设备、清理无效设备

4.2 获取与刷新 Token 的流程

获取 Token 是 Web 应用集成 FCM 的关键步骤。本节将介绍如何通过 Firebase SDK 获取 Token,并处理其刷新逻辑。

4.2.1 调用 getToken() 方法获取设备令牌

在 Web 端,使用 Firebase SDK 获取 Token 的主要方法是调用 messaging.getToken() ,前提是用户已经授权通知权限。

示例代码:
import { getMessaging, getToken } from "firebase/messaging";

const messaging = getMessaging();

// 获取 Token
getToken(messaging, { vapidKey: 'YOUR_PUBLIC_VAPID_KEY' })
  .then((currentToken) => {
    if (currentToken) {
      console.log('获取到 Token:', currentToken);
      // 发送到后端
      sendTokenToServer(currentToken);
    } else {
      console.log('未获得有效的 Token,可能用户未授权');
    }
  })
  .catch((err) => {
    console.error('获取 Token 失败:', err);
  });
参数说明:
参数 说明
messaging Firebase Messaging 实例
vapidKey VAPID 公钥,用于 Web Push 服务的身份验证
逻辑分析:
  1. 调用 getToken() 方法,传入 VAPID 公钥。
  2. 如果用户已授权通知权限,Firebase 会返回当前设备的 Token。
  3. 若未授权或 Token 不存在,需引导用户重新授权。
  4. 成功获取 Token 后,建议将其发送至后端进行持久化存储。

4.2.2 Token 刷新监听与处理策略

Token 并非一成不变,它可能因以下原因被刷新:

  • 用户清除浏览器缓存
  • 用户更改通知授权状态
  • Firebase 主动刷新 Token(通常每 6 个月一次)

因此,必须监听 Token 的刷新事件,并及时更新后端存储。

示例代码:
import { onTokenRefresh } from "firebase/messaging";

// 监听 Token 刷新事件
onTokenRefresh(messaging, () => {
  getToken(messaging, { vapidKey: 'YOUR_PUBLIC_VAPID_KEY' })
    .then((refreshedToken) => {
      console.log('Token 刷新成功:', refreshedToken);
      // 更新后端 Token
      updateTokenOnServer(refreshedToken);
    })
    .catch((err) => {
      console.error('Token 刷新失败:', err);
    });
});
逻辑分析:
  1. 使用 onTokenRefresh() 监听 Token 刷新事件。
  2. 一旦 Token 被刷新,调用 getToken() 获取新 Token。
  3. 将新 Token 发送至后端替换旧 Token。
  4. 建议在后端记录 Token 的更新时间,用于分析 Token 生效周期。

4.3 Token 的存储与管理实践

获取到 Token 后,开发者需将其安全地存储并管理,以支持后续的消息推送。

4.3.1 将 Token 存储至后端服务器

Token 应该以加密方式存储在后端数据库中,并与用户 ID 或设备 ID 关联。以下是一个简单的 Token 存储结构示例:

数据库表结构(MySQL):
CREATE TABLE user_tokens (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id VARCHAR(255) NOT NULL,
  token TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  expired BOOLEAN DEFAULT FALSE
);
存储流程图:
graph TD
  A[前端获取 Token] --> B[发送至后端接口]
  B --> C{后端验证 Token 有效性}
  C -->|有效| D[加密存储到数据库]
  C -->|无效| E[返回错误,提示重新授权]
  D --> F[与用户 ID 关联]

4.3.2 安全传输与 Token 的加密处理

Token 是敏感信息,必须在传输过程中加密,并在存储时进行脱敏处理。

安全传输建议:
  • 使用 HTTPS 传输 Token,防止中间人攻击。
  • 在请求头中添加认证 Token,如 JWT 或 Session Token,确保请求来源合法。
加密处理建议:
  • 使用 AES 或 RSA 加密 Token。
  • 不在日志、浏览器本地存储中明文保存 Token。
  • 定期清理过期 Token(如超过 30 天未更新的 Token)
示例代码(Node.js 加密 Token):
const crypto = require('crypto');

function encryptToken(token, secretKey) {
  const cipher = crypto.createCipher('aes-256-cbc', secretKey);
  let encrypted = cipher.update(token, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return encrypted;
}

const encryptedToken = encryptToken('fcm_token_abc123xyz789', 'my-secret-key');
console.log('加密后的 Token:', encryptedToken);
参数说明:
参数 说明
token 原始 FCM Token
secretKey 用于加密的密钥,应妥善保管
逻辑分析:
  1. 使用 AES-256-CBC 算法加密 Token。
  2. 密钥应通过安全方式管理,如环境变量或密钥管理服务(KMS)。
  3. 解密时需使用相同的密钥与算法。

小结与延伸讨论

  • Token 是 FCM 消息推送的基础,开发者必须掌握其生成、获取与刷新机制。
  • Token 的生命周期管理是保障推送服务稳定性的关键,建议结合后端建立 Token 更新与失效机制。
  • 在高并发场景中,建议使用队列机制异步处理 Token 的存储与更新操作,避免数据库压力过大。
  • 对于多端应用(Web + App),Token 应统一管理,并支持跨平台消息投递。

在下一章中,我们将深入探讨 FCM 消息的构建方式与数据格式定义,帮助开发者理解如何构造不同类型的消息以满足业务需求。

5. 消息构建与数据格式定义

5.1 FCM 消息类型与结构解析

5.1.1 通知消息与数据消息的区别

在 Firebase Cloud Messaging(FCM)中,消息主要分为两类: 通知消息(Notification Message) 数据消息(Data Message) 。它们的核心区别在于:

特性 通知消息 数据消息
用途 直接用于展示推送通知 用于传输自定义数据
客户端处理 由系统自动处理并显示通知 需要在客户端代码中手动处理
消息格式 JSON 格式,字段固定 完全可自定义的 JSON 数据
显示方式 自动弹出通知 由开发者决定是否显示通知
后台行为 应用处于后台时由系统处理 需要开发者处理 Service Worker 逻辑

通知消息 是一种预定义的消息结构,适用于简单的推送通知场景。例如,当应用在前台时,可以监听消息事件并选择是否显示通知;而当应用在后台时,系统会自动弹出通知。

数据消息 更加灵活,允许开发者自定义 payload 数据,适用于需要传输业务逻辑数据的场景。例如,发送一条用户订单更新的消息,客户端可以解析并根据数据内容执行特定操作,比如更新界面、播放声音或触发本地通知。

5.1.2 JSON 消息格式的组成结构

FCM 消息必须以 JSON 格式进行构建和发送。一个完整的 FCM 消息通常包含以下部分:

{
  "to": "device_token",
  "priority": "high",
  "notification": {
    "title": "系统通知",
    "body": "您有新的消息",
    "icon": "ic_launcher",
    "click_action": "https://example.com"
  },
  "data": {
    "type": "order_update",
    "order_id": "123456",
    "user_id": "7890"
  },
  "collapse_key": "update_order",
  "time_to_live": 60
}

字段说明:

  • to : 接收消息的目标设备令牌(Token),为字符串类型。
  • priority : 消息优先级,取值为 "normal" "high" ,高优先级会立即送达。
  • notification : 通知消息内容,包含标题、正文、图标等字段。
  • data : 自定义数据负载,用于传输业务逻辑数据。
  • collapse_key : 消息合并键,相同键的消息在设备离线时只会保留最新的一条。
  • time_to_live : 消息生存时间(TTL),单位为秒,消息在此时间后将不再发送。

⚠️ 注意:通知消息和数据消息可以同时存在,但在实际使用中建议根据需求选择合适的消息类型。

5.2 消息字段详解与自定义数据封装

5.2.1 必填字段(to、priority)与可选字段(collapse_key)

必填字段
  • to :消息的接收者,通常为设备令牌(Token),格式为字符串。该字段是所有消息的必需字段。
  • priority :消息的优先级,决定消息的传输方式。取值如下:
优先级 描述
"normal" 默认优先级,适合非紧急消息
"high" 高优先级,适合需要立即送达的消息(如通知)
可选字段
  • collapse_key :用于标识一组可以合并的消息。如果多个消息具有相同的 collapse_key 并且目标设备离线,则只保留最后一条消息。例如,在订单更新场景中,使用 collapse_key: "update_order" 可以确保设备在上线后只收到最新的订单状态。

  • time_to_live (TTL) :消息的有效时间,单位为秒。若设备在该时间内无法接收消息,FCM 将不再尝试发送。默认值为 4 周(2419200 秒)。

示例代码:构造基础消息结构
const message = {
  to: 'device_token_here',
  priority: 'high',
  notification: {
    title: '订单更新',
    body: '您的订单状态已更新,请查看最新信息',
    icon: '/icons/notification.png',
    click_action: 'https://yourapp.com/orders'
  },
  data: {
    type: 'order_update',
    order_id: '202310011234',
    status: 'shipped'
  },
  collapse_key: 'order_update',
  time_to_live: 86400 // 24小时
};

逻辑分析:

  • 第 1 行定义了目标设备的 Token,开发者需替换为真实值。
  • 第 2 行设置高优先级,确保消息即时送达。
  • 第 3~8 行是通知消息结构,用于在客户端展示。
  • 第 9~13 行是自定义数据结构,用于业务处理。
  • 第 14 行设置消息合并键,确保设备上线后只收到最新消息。
  • 第 15 行设置消息有效期为 24 小时。

5.2.2 自定义数据(data payload)的构建方式

自定义数据字段( data )是开发者可以完全控制的消息部分,适用于需要传递业务逻辑信息的场景。例如,传递订单 ID、用户信息、事件类型等。

构建建议:
  • 字段命名清晰 :如 "type" "order_id" "timestamp" 等。
  • 避免嵌套过深 :建议使用扁平结构,方便客户端解析。
  • 类型安全 :尽量使用字符串、数字、布尔值,避免传递复杂对象。
示例:自定义数据字段的使用
{
  "data": {
    "event": "new_message",
    "sender_id": "user_123",
    "message_id": "msg_456",
    "timestamp": "1672531199"
  }
}

字段说明:

  • event :表示事件类型,用于客户端判断如何处理。
  • sender_id :消息发送者 ID。
  • message_id :消息唯一标识,用于后续查询或更新。
  • timestamp :消息时间戳,用于排序或有效期判断。

✅ 实践建议:结合 notification data 字段,可以实现“前台展示通知 + 后台处理业务逻辑”的完整流程。

5.3 消息生命周期中的状态标识与行为控制

5.3.1 消息生存时间(TTL)设置

消息的生存时间(Time To Live, TTL)决定了消息在 FCM 服务器上等待设备上线的最大时间。如果设备在 TTL 时间内未连接,消息将被丢弃。

TTL 设置方式:
  • 在发送请求中使用 time_to_live 字段。
  • 单位为秒,取值范围:0 ~ 2419200(28 天)。
  • 默认值为 2419200(28 天)。
示例:设置不同 TTL 值
{
  "to": "device_token",
  "priority": "normal",
  "data": {
    "type": "reminder",
    "content": "请查看今日待办事项"
  },
  "time_to_live": 3600
}

分析:

  • 第 6 行设置 TTL 为 3600 秒(1 小时),适用于时效性强的提醒类消息。
  • 若设备在 1 小时内未上线,则消息将不会被发送。

5.3.2 消息重复与合并机制(collapse_key)

在设备离线期间,可能会有多个消息被发送到该设备。为了避免消息堆积,FCM 提供了 collapse_key 机制。

工作原理:
  • 具有相同 collapse_key 的消息会被合并,仅保留最后一条。
  • FCM 最多保留 4 个不同的 collapse_key
示例:订单更新合并
{
  "to": "device_token",
  "priority": "high",
  "data": {
    "type": "order_update",
    "order_id": "202310011234",
    "status": "shipped"
  },
  "collapse_key": "order_update"
}

分析:

  • 如果发送多条订单更新消息,且 collapse_key 都为 "order_update" ,则设备上线后只会收到最后一条消息。
  • 此机制适用于频繁更新的场景,如订单状态、库存变动等。
流程图:collapse_key 合并机制
graph TD
    A[发送多条消息] --> B{是否有相同 collapse_key?}
    B -->|是| C[保留最后一条消息]
    B -->|否| D[全部保留]
    C --> E[设备上线后只接收最后一条]
    D --> F[设备上线后接收所有消息]

图解:

  • 系统首先判断是否具有相同的 collapse_key
  • 如果有,仅保留最后一条消息。
  • 如果没有,所有消息都会保留并按顺序发送。

总结

在本章中,我们详细解析了 FCM 消息的构建方式,包括通知消息与数据消息的区别、JSON 格式结构、核心字段说明,以及消息生命周期中的关键控制机制。通过合理使用 priority time_to_live collapse_key ,开发者可以更好地控制消息的行为,提升用户体验与系统效率。

下一章我们将深入探讨如何使用 Firebase Admin SDK 发送消息,包括初始化、消息构造与错误处理等内容。

6. 使用 Firebase Admin SDK 发送消息

Firebase Cloud Messaging(FCM)不仅支持通过控制台或 REST API 发送消息,还提供了强大的 Firebase Admin SDK,允许开发者在服务器端构建并发送推送消息。Admin SDK 提供了更灵活的消息构造能力,适用于需要频繁发送、批量处理、或基于用户行为动态构建消息的场景。本章将深入讲解如何在 Node.js 环境中使用 Firebase Admin SDK 发送通知消息与数据消息,并详细说明错误处理与响应解析机制。

6.1 Admin SDK 的安装与初始化

在使用 Firebase Admin SDK 发送消息之前,需要完成 SDK 的安装和初始化。这一步是整个推送流程的起点,决定了后续消息发送的权限和能力。

6.1.1 Node.js 环境搭建与 SDK 安装

首先,确保你已经安装了 Node.js 环境(建议版本 14.x 或更高)。你可以通过以下命令检查 Node.js 是否已安装:

node -v
npm -v

接下来,创建一个新的项目目录并初始化 npm:

mkdir fcm-admin-sdk-demo
cd fcm-admin-sdk-demo
npm init -y

然后安装 Firebase Admin SDK:

npm install firebase-admin

此时,你已经在项目中引入了 Firebase Admin SDK 的基础模块。

6.1.2 使用服务账号密钥文件初始化 SDK

为了获得向 FCM 发送消息的权限,你需要从 Firebase 控制台下载服务账号的 JSON 密钥文件。

操作步骤如下:

  1. 打开 Firebase 控制台 ,选择你的项目。
  2. 点击左下角的齿轮图标,进入“项目设置”。
  3. 在“服务账号”标签页中,点击“生成新私钥”,系统会下载一个 JSON 文件(例如 serviceAccountKey.json )。
  4. 将该文件放入项目根目录,如 ./serviceAccountKey.json

接下来,使用该密钥文件初始化 Admin SDK:

const admin = require('firebase-admin');

const serviceAccount = require('./serviceAccountKey.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});

参数说明:
- admin.credential.cert(serviceAccount) :使用服务账号密钥文件进行身份验证。
- admin.initializeApp() :初始化 Firebase 应用实例,这是调用任何 Firebase API 的前提。

代码逻辑分析:

  • 第1行引入了 firebase-admin 模块。
  • 第3行引入了服务账号的 JSON 文件,该文件包含了私钥和项目信息。
  • 第5-7行调用 initializeApp 初始化 SDK,并传入认证信息。

完成初始化后,即可使用 admin.messaging() 来构建并发送消息。

6.2 构建并发送通知与数据消息

在 Firebase Admin SDK 中,你可以通过 admin.messaging() 构建不同类型的消息,包括通知消息(Notification)和数据消息(Data)。消息可以通过设备令牌(Token)发送给单个设备,也可以通过多播方式发送给多个设备。

6.2.1 构造消息对象并发送至单个设备

以下是一个向单个设备发送通知消息的示例:

const message = {
  notification: {
    title: '你好!',
    body: '这是一条来自 Firebase Admin SDK 的通知消息。',
  },
  token: '设备令牌',
};

admin.messaging().send(message)
  .then((response) => {
    console.log('消息发送成功:', response);
  })
  .catch((error) => {
    console.log('消息发送失败:', error);
  });

参数说明:
- notification.title body :通知消息的标题与正文。
- token :目标设备的注册令牌,通过 getToken() 获取。
- admin.messaging().send() :发送消息的方法。

代码逻辑分析:

  • 构造了一个包含 notification token 的消息对象。
  • 调用 send() 方法发送消息,并使用 Promise 捕获成功或失败的状态。

如果你希望发送数据消息而非通知消息,可以使用 data 字段代替 notification

const message = {
  data: {
    score: '85',
    time: '14:30',
  },
  token: '设备令牌',
};

此时,消息不会在通知栏显示,而是作为数据传递给应用进行自定义处理。

6.2.2 批量发送与多播消息处理

Admin SDK 支持通过 sendMulticast() 方法一次性发送消息给多个设备,适用于广播通知或定向推送。

const message = {
  notification: {
    title: '多播消息',
    body: '这是一条发送给多个设备的通知消息',
  },
  tokens: ['token1', 'token2', 'token3'],
};

admin.messaging().sendMulticast(message)
  .then((response) => {
    console.log(`${response.successCount} 条消息发送成功`);
    console.log(`${response.failureCount} 条消息发送失败`);
  })
  .catch((error) => {
    console.log('多播消息发送失败:', error);
  });

参数说明:
- tokens :一个包含多个设备令牌的数组。
- sendMulticast() :用于发送多播消息的方法。
- response.successCount failureCount :用于统计成功与失败数量。

流程图:多播消息发送流程

graph TD
    A[构造消息对象] --> B[调用 sendMulticast()]
    B --> C{发送结果}
    C -->|成功| D[输出成功数量]
    C -->|失败| E[输出失败原因]

通过多播功能,开发者可以高效地管理消息推送任务,减少重复调用接口的次数,提高服务器性能。

6.3 错误处理与响应解析

在实际开发中,消息发送可能会因网络问题、令牌失效、权限配置错误等原因失败。因此,合理的错误处理和响应解析机制至关重要。

6.3.1 发送失败原因分析与日志记录

当消息发送失败时, catch() 会捕获异常。常见的错误原因包括:

错误码 描述
messaging/invalid-argument 参数错误,如 token 格式不正确
messaging/registration-token-not-registered 设备令牌已失效或未注册
messaging/invalid-registration-token 无效的注册令牌
messaging/mismatched-credential 使用了错误的项目密钥

示例代码:错误处理与日志记录

admin.messaging().send(message)
  .then((response) => {
    console.log('消息发送成功:', response);
  })
  .catch((error) => {
    console.error('消息发送失败:', error.code, error.message);
    // 将错误信息写入日志文件
    fs.appendFileSync('error.log', `${new Date()}: ${error.code} - ${error.message}\n`);
  });

参数说明:
- error.code :错误代码,用于判断错误类型。
- error.message :错误详细描述。
- fs.appendFileSync() :将错误信息写入日志文件,便于后续排查。

6.3.2 成功发送的响应结构与状态码解析

当消息成功发送后, then() 会返回一个响应对象,其结构如下:

{
  "name": "projects/your-project-id/messages/0:1234567890123456",
  "messageId": "0:1234567890123456"
}

对于多播消息,响应结构如下:

{
  "responses": [
    { "success": true, "messageId": "..." },
    { "success": false, "error": { "code": "messaging/invalid-argument", ... } }
  ],
  "successCount": 2,
  "failureCount": 1
}

字段说明:
- responses :每个设备的发送结果数组。
- successCount failureCount :分别表示成功与失败的数量。
- error.code :失败时的错误代码,可用于判断错误类型。

表格:多播响应字段说明

字段名 类型 说明
responses Array 每个设备的发送结果
successCount Number 成功发送的设备数量
failureCount Number 发送失败的设备数量
response.success Boolean 单个设备是否发送成功
response.messageId String 成功时的消息 ID
response.error.code String 失败时的错误代码

通过解析响应结构,开发者可以实时监控消息发送状态,并对失败的消息进行重试或记录处理。

总结

使用 Firebase Admin SDK 发送消息是一种高效且灵活的方式,尤其适合需要在服务器端动态控制消息内容、批量发送或集成到业务逻辑中的场景。通过 Node.js 环境搭建、SDK 初始化、消息构造、多播处理以及完善的错误处理机制,开发者能够实现稳定、可靠的消息推送系统。

本章内容为实际开发中构建推送服务提供了完整的技术路径和实践指南,下一章将深入介绍如何通过 REST API 发送消息,进一步扩展开发者的技术工具箱。

7. 使用 REST API 发送消息

7.1 FCM REST API 基础知识

Firebase Cloud Messaging 提供了 REST API 接口,允许开发者通过 HTTP 请求直接向设备发送推送消息。这种方式适用于不使用 Firebase Admin SDK 的后端服务,比如使用 PHP、Python、Java、Go 等语言构建的系统。

7.1.1 API 端点与认证机制(使用服务器密钥)

FCM 的 REST API 端点地址如下:

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

为了认证请求,需要在请求头中携带服务器密钥。服务器密钥可以在 Firebase 控制台的【项目设置】 → 【云消息传递】 → 【服务器密钥】中获取。

请求头示例:

Content-Type: application/json
Authorization: key=YOUR_SERVER_KEY

7.1.2 构建 POST 请求的请求头与请求体

请求头
- Content-Type : 必须为 application/json
- Authorization : 使用 key=你的服务器密钥

请求体示例 (发送通知消息):

{
  "to": "设备令牌(Token)",
  "notification": {
    "title": "你好,世界",
    "body": "这是来自 FCM REST API 的推送通知"
  }
}

请求体示例 (发送数据消息):

{
  "to": "设备令牌(Token)",
  "data": {
    "type": "alert",
    "message": "这是数据消息内容"
  }
}

7.2 实战:使用 Postman 或代码发送消息

7.2.1 使用 Postman 发送测试消息

你可以使用 Postman 工具快速测试 FCM REST API 的调用流程。

操作步骤:

  1. 打开 Postman,选择 POST 请求方式。
  2. 地址栏输入: https://fcm.googleapis.com/fcm/send
  3. 点击 Headers 标签页,添加以下内容:
Key Value
Content-Type application/json
Authorization key=你的服务器密钥(替换为真实值)
  1. 点击 Body 标签页,选择 raw ,然后选择 JSON 格式。
  2. 输入如下 JSON 内容(替换 to 字段为有效的设备 Token):
{
  "to": "你的设备Token",
  "notification": {
    "title": "Postman 测试",
    "body": "这条消息是通过 Postman 发送的!"
  }
}
  1. 点击 Send 按钮发送请求。

7.2.2 使用 curl 或 JavaScript 发送请求

使用 curl 发送:
curl -X POST -H "Content-Type: application/json" \
-H "Authorization: key=你的服务器密钥" \
-d '{
  "to": "你的设备Token",
  "notification": {
    "title": "curl 发送",
    "body": "这条消息是通过 curl 发送的!"
  }
}' https://fcm.googleapis.com/fcm/send
使用 JavaScript(Node.js)发送:
const https = require('https');

const serverKey = '你的服务器密钥';
const deviceToken = '你的设备Token';

const message = JSON.stringify({
  to: deviceToken,
  notification: {
    title: 'Node.js 发送',
    body: '这条消息是通过 Node.js 脚本发送的!'
  }
});

const options = {
  hostname: 'fcm.googleapis.com',
  path: '/fcm/send',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `key=${serverKey}`
  }
};

const req = https.request(options, (res) => {
  let data = '';
  res.on('data', (chunk) => { data += chunk; });
  res.on('end', () => {
    console.log('响应状态码:', res.statusCode);
    console.log('响应内容:', data);
  });
});

req.on('error', (error) => {
  console.error('请求错误:', error);
});

req.write(message);
req.end();

7.3 REST API 使用中的注意事项

7.3.1 请求频率限制与错误码处理

FCM 对 REST API 的请求频率有限制,具体如下:

  • 每秒请求上限 :默认为每秒 1000 个请求。
  • 每分钟请求上限 :根据项目等级不同,上限可能不同,可通过升级 Firebase 套餐提升限制。
常见 HTTP 错误码说明:
状态码 含义描述
400 请求格式错误,如 JSON 语法错误或缺少必要字段
401 认证失败,如服务器密钥无效或未提供
403 权限不足,服务器密钥未启用 FCM API
410 设备 Token 已失效或被注销
500 服务器内部错误,可重试
503 服务暂时不可用,建议延迟后重试

建议在发送请求后,对响应内容进行解析并记录日志,以便排查错误。

7.3.2 安全性建议与密钥保护策略

服务器密钥具有较高权限,必须妥善保管:

  • 避免硬编码在客户端代码中 :密钥应存储在后端服务中,避免暴露在前端代码或公开仓库中。
  • 使用环境变量或配置中心 :在部署时通过环境变量注入密钥,或使用配置管理工具(如 Vault、AWS Secrets Manager)进行保护。
  • 定期轮换密钥 :可在 Firebase 控制台中生成新的服务器密钥,并替换旧密钥,提升安全性。
  • 限制 IP 白名单 :可通过 Google Cloud Console 配置 API 密钥的访问权限,限制调用来源。

提示 :REST API 适合中轻量级推送需求,如需大规模推送或复杂的消息管理,推荐使用 Firebase Admin SDK。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:Firebase 消息服务(基于 Firebase Cloud Messaging)支持 Android、iOS 和 Web 应用的实时消息推送,提升用户参与度和交互体验。本教程围绕“已发送 Firebase 消息”这一状态展开,详细讲解 Firebase 消息服务的配置与实现流程,涵盖项目设置、SDK 集成、设备令牌获取、消息构建与发送、客户端消息处理等关键环节。适合希望掌握推送通知开发的移动与 Web 开发者。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐