Flutter应用每次运行生成新Device Token?如何实现仅首次生成
解决方案
要实现仅在应用首次安装时将FCM Token保存到Firestore,需结合本地存储标记和Token刷新监听来避免重复存储,同时处理Token更新的场景。
步骤1:添加本地存储依赖
在pubspec.yaml中引入shared_preferences用于记录是否已保存过Token:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2 firebase_core: ^2.15.0 firebase_messaging: ^14.6.5 cloud_firestore: ^4.8.4
步骤2:修改Token处理逻辑
导入依赖
import 'package:shared_preferences/shared_preferences.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
初始化方法修改
Future init() async { final prefs = await SharedPreferences.getInstance(); // 读取本地是否已保存过Token的标记 final hasSavedToken = prefs.getBool('has_saved_token') ?? false; if (!hasSavedToken) { // 首次安装:获取Token并保存 final token = await FirebaseMessaging.instance.getToken(); if (token != null) { await saveTokens(token); // 标记已保存Token await prefs.setBool('has_saved_token', true); } } // 监听Token刷新事件(FCM Token可能会在特定场景下更新) FirebaseMessaging.instance.onTokenRefresh.listen((newToken) async { // 删除Firestore中的旧Token final oldToken = await FirebaseMessaging.instance.getToken(); if (oldToken != null) { await FirebaseFirestore.instance.collection('deviceTokens') .where('token', isEqualTo: oldToken) .get() .then((snapshot) { for (var doc in snapshot.docs) { doc.reference.delete(); } }); } // 保存新Token await saveTokens(newToken); // 更新本地标记 final prefs = await SharedPreferences.getInstance(); await prefs.setBool('has_saved_token', true); }); }
保存Token方法优化(避免重复添加)
Future<void> saveTokens(String token) async { try { // 先检查Firestore中是否已有该Token final querySnapshot = await FirebaseFirestore.instance.collection('deviceTokens') .where('token', isEqualTo: token) .get(); if (querySnapshot.docs.isEmpty) { await FirebaseFirestore.instance.collection('deviceTokens').add({ 'token': token, 'createdAt': FieldValue.serverTimestamp(), // 可选:添加创建时间 }); } } catch (e) { print(e); } }
逻辑说明
- 首次安装启动时,本地无保存标记,会获取Token并同步到Firestore,同时标记已保存
- 后续启动时,读取本地标记直接跳过保存流程
- 当FCM Token因应用重装、数据清除或系统更新等场景刷新时,自动删除旧Token并保存新Token,确保Firestore中始终是有效Token
内容的提问来源于stack exchange,提问作者ASMA
相关产品推荐
相关产品推荐

