Registration Token 是设备的唯一标识符,Firebase Cloud Messaging (FCM) 使用它来提供推送通知。每个设备上的每个应用程序都会获得自己的令牌,没有它就无法发送通知。据 Firebase, 2025 报道,Registration Token 在应用程序首次启动时自动生成,并可能在特定条件下发生变化。
主要内容
Registration Token — Firebase Cloud Messaging 分配给每个应用程序实例的唯一字符串,最长可达 4096 个字符。令牌根据应用程序、设备和设备上 Google 帐户的标识符形成。
Registration Token 由以 Base64 格式编码的随机字符序列组成。FCM 将此令牌作为 传递地址 使用 — 服务器端将通知发送到令牌,FCM 将其路由到特定设备。没有令牌,无法将推送通知发送给特定用户。
Registration Token 不应与 Device ID(IMEI)或 Advertising ID 混淆。Device ID 是设备的硬件标识符,而 Advertising ID 用于广告目的。Registration Token 绑定于应用程序和设备的组合,一个设备可以为不同的应用程序拥有多个令牌。
| 标识符 | 用途 | 可变性 |
|---|---|---|
| Registration Token | 提供 FCM 推送通知 | 可能变化 |
| Device ID (IMEI) | 设备标识 | 永久 |
| Advertising ID | 精准广告 | 可重置 |
| Instance ID | 过时的 Firebase 机制 | 删除时变化 |
FCM 可以在多种情况下将 Registration Token 视为无效。如果应用程序从设备上删除,令牌将自动注销。从备份中恢复数据到新设备时,旧令牌将停止工作。尝试向旧令牌发送通知时,Firebase 会返回 UNREGISTERED 状态。
Firebase Cloud Messaging 在应用程序首次启动时生成 Registration Token,当调用 getToken() 方法时。该过程包括验证 Google Play Services 凭据和在 Firebase 基础设施中注册应用程序。
当设备首次运行集成了 FCM SDK 的应用程序时,会发生以下情况。Firebase SDK 检查设备上是否存在 Google Play Services。然后,SDK 向 Firebase 服务器发送请求,传递应用程序标识符和设备信息。Firebase 服务器创建新令牌并将其返回给应用程序。
FCM 使用基于长连接的架构。接收到 Registration Token 后,设备通过 Android 上的 STOMP 协议 或 iOS 上的 APNs 渠道 与 Firebase 服务器建立永久连接。当服务器端将通知发送到令牌时,FCM 通过令牌查找设备并传递负载。
FCM 可以在以下情况下重新生成 Registration Token。从备份中恢复应用程序到新设备时。删除并重新安装应用程序时。通过系统设置清除应用程序数据时。在设备上登录另一个 Google 帐户 时。Firebase 建议始终处理 onNewToken 回调以跟踪变化。
在 Android 上,Registration Token 通过 Firebase Messaging SDK 获取。该过程因 SDK 版本而异 — 在新版本中,使用 FirebaseInstallations API 代替过时的 FirebaseInstanceId。
从 Firebase SDK 版本 21.0.0 开始,getToken() 方法通过 FirebaseMessaging 调用。此方法自动管理令牌的生命周期并订阅其更新。
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
sendRegistrationToServer(token)
}
private fun sendRegistrationToServer(token: String) {
// 将令牌发送到服务器端
Log.d("FCM", "New token: $token")
}
init {
FirebaseMessaging.getInstance()
.getToken()
.addOnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w("FCM", "获取 FCM 令牌失败")
return@addOnCompleteListener
}
val token = task.result
sendRegistrationToServer(token)
}
}
}
在某些场景下,令牌不是在服务中需要,而是直接在 Activity 或 ViewModel 中需要。为此,可以在应用程序生命周期的合适位置调用 getToken()。重要的是不要在未处理异步的情况下从主线程调用此方法。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
getFCMToken()
}
private fun getFCMToken() {
FirebaseMessaging.getInstance().getToken()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
val token = task.result
Log.d("FCM", "Token: $token")
}
}
}
}
在旧版本的 Firebase SDK(版本 20.x 之前)中,令牌通过 FirebaseInstanceId.getInstance().getToken() 获取。此方法已被标记为 deprecated,不建议在新项目中使用。维护旧代码的开发人员应迁移到 FirebaseInstallations API。
在 iOS 上,获取 Registration Token 的过程在架构上有所不同 — FCM 通过 Apple Push Notification service (APNs) 工作。Firebase SDK 从 APNs 接收唯一的 device token,将其转换为 FCM 格式并传递给应用程序。
要在 iOS 上使 FCM 工作,需要在 Firebase 控制台中配置 APNs 证书或密钥。应用程序必须通过 UNUserNotificationCenter 请求通知权限。接收到 APNs 令牌后,Firebase SDK 自动生成 Registration Token。
import FirebaseMessaging
import UserNotifications
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
application: UIApplication,
didFinishLaunchingWithOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
requestNotificationAuthorization()
return true
}
private func requestNotificationAuthorization() {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge])
}
}
extension AppDelegate: MessagingDelegate {
func messaging(
messaging: Messaging,
didReceiveRegistrationToken fcmToken: String?
) {
Log.d("FCM", "Token: \(fcmToken ?? "")")
sendTokenToServer(token: fcmToken)
}
}
iOS 上的 Registration Token 与 Android 令牌相比尺寸较小,因为它基于 APNs device token。当 APNs 令牌变化时(在从备份中恢复设备或重新安装应用程序时发生),Firebase SDK 会自动更新 FCM 令牌。
管理生命周期 Registration Token 对于稳定提供推送通知至关重要。如果服务器端存储的是旧令牌,通知将无法传递,并且 Firebase 会返回 UNREGISTERED 错误。
Firebase SDK 提供两种机制来跟踪令牌变化。在 Android 上,使用 FirebaseMessagingService 中的 onNewToken 回调。在 iOS 上 — 使用 messaging:didReceiveRegistrationToken 代理。两者都在每次令牌更新时被调用。
// 将令牌保存到 SharedPreferences 并发送到服务器
class TokenManager(private val context: Context) {
companion object {
private const val PREFS_TOKEN_KEY = "fcm_registration_token"
}
fun saveToken(token: String) {
val prefs = PreferenceManager
.getDefaultSharedPreferences(context)
prefs.edit().putString(PREFS_TOKEN_KEY, token).apply()
}
fun getSavedToken(): String? {
val prefs = PreferenceManager
.getDefaultSharedPreferences(context)
return prefs.getString(PREFS_TOKEN_KEY, null)
}
}
服务器端应将 Registration Token 与 用户标识符 关联存储。更新令牌时,客户端将新令牌发送给服务器,服务器替换旧令牌。建议保留令牌历史:如果通知未成功发送到新令牌,可以尝试使用旧令牌。
Firebase 可以在多种情况下返回获取令牌错误。设备上缺少 Google Play Services — 无法获取令牌。超出 FCM 请求配额 — 必须在重试时实现 指数退避。令牌过期 — SDK 自动请求新令牌。
| 情况 | 结果 | 开发人员的操作 |
|---|---|---|
| 删除应用程序 | 令牌被注销 | 从数据库中删除令牌 |
| 从备份中恢复 | 新令牌 | 在数据库中更新 |
| 重置 Google Play Services | 令牌重新生成 | 处理 onNewToken |
| 令牌过期 | 自动更新 | 订阅更新 |
常见问题
检查设备上是否存在 Google Play Services、google-services.json 文件的正确性以及 Firebase SDK 版本。确保应用程序具有访问互联网的权限。
令牌可能在删除和重新安装应用程序、清除数据、从备份中恢复或登录另一个 Google 帐户 时发生变化。没有固定的时间间隔。
可以,设备上的每个应用程序都会获得自己的 FCM 令牌。如果设备上安装了三个使用 Firebase 的应用程序,每个都将拥有自己的 唯一 Registration Token。
通过 Firebase 控制台或 FCM HTTP API 发送测试通知。如果令牌无效,API 将返回 UNREGISTERED 或 NOT_FOUND 错误。
Registration Token 不是密钥,但它的泄露会允许向用户的设备发送通知。将令牌存储在 受保护的数据库 中,并使用 HTTPS 进行传输。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。