推送通知是服务器在应用程序关闭时也能发送到移动设备的消息。根据 Google Firebase, 2024 的数据,推送通知通过专门的服务进行处理——Android 上的 FCM 和 iOS 上的 APNS,它们支持同时向数百万台设备进行实时投递。它们已成为现代移动应用中用户体验不可或缺的一部分。
要点
推送通知是应用服务器在用户没有明确请求的情况下发送到用户设备的简短消息。它们以横幅、图标标记或声音信号的形式显示,吸引用户对应用程序的注意力并通知重要事件。
推送通知由标题、消息正文和可选数据(payload)组成。与短信不同,推送通知对用户免费,并通过云服务基础设施投递——Android 使用 FCM,iOS 使用 APNS。推送通知的主要目的:提高参与度、通知事件和让用户返回应用。
使用统计数据显示,正确配置的推送通知可将应用留存率提高 30-60%。然而,过于频繁的通知会导致取消订阅——如果每天发送超过三次,超过 60% 的用户会关闭通知。
推送系统包含三个组件:应用服务器(app server)、平台服务(FCM/APNS)和设备上的客户端应用程序。服务器向平台服务发送请求,平台服务通过与操作系统的永久连接将通知投递到目标设备。
投递机制推送通知基于设备和平台服务之间的永久连接。操作系统维护一个加密的通信通道,所有推送消息都通过该通道传输。
首次启动时,应用程序请求发送通知的权限,并从 FCM 或 APNS 接收唯一设备令牌。此令牌是长达 4 KB 的字符串,唯一标识应用程序实例。令牌在重新安装应用或从备份恢复设备时更改。
class FirebaseMessagingService :
FirebaseMessagingService() {
override fun onNewToken(token: String) {
sendTokenToServer(token)
}
override fun onMessageReceived(
message: RemoteMessage
) {
showNotification(message.notification)
}
}
应用服务器向 FCM API 或 APNS API 发送 HTTP 请求,指定目标令牌、标题、正文和附加数据。平台服务响应投递状态:success、invalid token(设备已删除应用)或 rate-limited(超出发送频率)。
fetch("https://fcm.googleapis.com/fcm/send", {
method: "POST",
headers: {
"Authorization": "key=AIzaSy...",
"Content-Type": "application/json"
},
body: JSON.stringify({
to: "device_token_here",
notification: {
title: "将令牌发送到您自己的服务器",
body: "您有一个新通知!"
}
})
})
在 FCM 和 APNS 之间的选择取决于目标平台。FCM 支持 Android 和 iOS,APNS 仅支持 Apple 生态系统。让我们看看对于跨平台移动应用开发而言重要的关键差异。
FCM 是基于 Google Play Services 运行的 Google 服务。它支持两种投递方案:自动显示的通知(display notifications)和应用程序自行处理的数据通知。FCM 是免费的,并且对发送消息的数量没有限制。
APNS 是 Apple 的服务,支持最大 10 MB 的多媒体附件(图片、视频、音频)。通过 APNS 发送需要 TLS 证书或身份验证密钥。APNS 限制向单个设备的发送频率——每分钟不超过 150 条通知,之后会启用速率限制。
| 特性 | FCM | APNS |
|---|---|---|
| 平台 | Android、iOS、Web | iOS、macOS、watchOS |
| 要求 | Google Play Services | Apple Developer Program |
| 媒体 | 最大 4 KB(数据) | 最大 10 MB(附件) |
| 优先级 | normal/high | immediate/power-saving |
| 费用 | 免费 | 免费(需要账户) |
推送通知根据显示方式和目的进行分类。了解通知类型有助于为每个用户交互场景选择合适的策略。
最常见的类型——显示通知,包含标题和正文。操作系统自动在系统面板、锁屏和横幅中显示。开发人员可以配置声音、振动、图标标记和用于直接操作的按钮(回复、打开、拒绝)。
数据通知仅包含 payload,没有视觉显示。应用程序在后台处理它们:同步数据、更新缓存或启动下载。在 Android 上,数据通知保证投递;在 iOS 上,仅在应用程序激活时或通过后台获取(background fetch)时投递。
现代移动操作系统支持包含图片、GIF、视频和音频的扩展和媒体通知。在 iOS 上通过 UNNotificationAttachment 实现,在 Android 上通过 BigPictureStyle 和 InboxStyle 来定制通知在系统面板中的外观。
静默通知不向用户显示,用于后台同步。在 iOS 上,它们对于在打开应用前更新数据等任务具有高优先级。Android 将它们视为具有最低优先级的数据通知。
配置推送通知需要在基础设施、服务器端和客户端代码层面采取措施。让我们看看跨平台移动项目的典型流程。
对于 Android,需要在 Firebase Console 中创建项目,将 google-services.json 添加到项目中,并配置 FirebaseMessagingService。设备令牌通过 FirebaseInstanceId 或 FirebaseMessaging.getInstance().token 获取,然后在首次启动或更改时通过 API 发送到服务器。
对于 iOS,需要订阅 Apple Developer Program,在 Developer Portal 中创建推送证书或 APNS 密钥,并在 Xcode 中启用 Capability Push Notifications。通过 UIApplication.shared.registerForRemoteNotifications 进行通知注册,在 AppDelegate 中接收 deviceToken。
import UIKit
import UserNotifications
@main
class AppDelegate: UIResponder,
UIApplicationDelegate {
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken
deviceToken: Data
) {
let token = deviceToken
.map { String.format("%02x", $0) }
.joined()
// 将 token 发送到自己的服务器
}
}
在服务器端,推送通知通过 REST API 或 Admin SDK 发送。对于 FCM,使用 Firebase Admin SDK(适用于 Node.js、Java、Python、Go);对于 APNS,使用 pusher 库(Java 使用 pushy,Node.js 使用 apn2)。建议将令牌存储在数据库中,并带有最后更新时间戳。
推送通知的安全性至关重要,因为敏感数据可能通过它们传输。两个平台都提供基本的保护机制,但开发人员必须正确使用它们。
推送通知的 payload 可能包含用户的个人数据:姓名、交易金额、消息链接。即使 FCM/APNS 与设备之间的通信通道是加密的,当第三方软件拦截通知时,数据仍可能在应用程序层面被截获。建议在服务器上使用 AES-256 算法加密敏感 payload,并使用存储在 Keychain(iOS)或 EncryptedSharedPreferences(Android)中的密钥在设备上解密。
设备令牌是一个会话标识符,在设备被破解或流量被拦截时可能会被泄露。应用服务器应在发送前检查令牌:与数据库比对、跟踪非活动令牌,并在重复出现 InvalidToken 错误时删除它们。FCM 和 APNS 对无效令牌返回 InvalidRegistration 状态——不要忽略它。
没有频率控制,推送通知可能成为垃圾邮件工具,激怒用户并降低留存率。在服务器上设置限制:每个用户每小时不超过 5 条通知,不超过 3 条相同的消息。对于事务性通知(订单确认、密码更改),限制可能更高——每小时最多 10 条,因为它们携带关键重要信息。在发送 API 级别使用速率限制,以防止攻击者通过您的服务器触发批量发送。
常见问题
可以。直接连接到 APNS 在 Android 上不受支持——对于没有 Google Play Services 的设备,使用华为移动服务(HMS)和自有的 WebSocket 连接等替代方案。然而,FCM 因其免费性和可靠性仍然是大多数应用的标准。
FCM 和 APNS 将最后一条通知保存在其服务器上,并在连接恢复时投递。每台设备上只保存每个应用的最后一个通知,因此在长时间没有网络的情况下,中间消息会丢失。
最常见的原因是 APNS 推送证书过期(有效期为 1 年)、设备令牌无效、设置中关闭了通知或开启了省电模式。在 Apple Developer Console 中检查证书,并确保应用程序通过 UNUserNotificationCenter 请求权限。
在 Android 上,在 NotificationCompat.Builder 中使用 PendingIntent,通过 Intent 跟踪打开。在 iOS 上——使用 UNUserNotificationCenterDelegate.userNotificationCenter(_:didReceive:withCompletionHandler:) 方法。FCM 为每条发送的通知提供投递和打开报告。
影响很小——推送通知不保持永久连接;操作系统为所有应用使用统一的系统通道,最大限度地降低了总能耗。频繁发送(每 5 分钟)会消耗更多能量用于唤醒设备和退出睡眠模式。iOS 上的静默通知会因在后台激活应用程序处理接收到的数据而消耗更多电量。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。