You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 13:35:17