Flutter FCM调用subscribeToTopic传入注册token报isValidTopic错误如何解决
问题根源
你触发报错的直接原因是直接将FCM设备注册token作为参数传入了subscribeToTopic方法,FCM对主题名称有严格的格式校验规则:
- 仅允许包含大小写英文字母、数字、下划线
_、减号-、英文句号. - 长度要求1~900个字符
从你的日志可以看到,获取到的FCM token包含冒号:,属于规则不允许的特殊字符,所以触发了isValidTopic的断言失败。
解决方案
根据你的实际业务需求,可选两种实现方式:
方案1:无需订阅专属主题,直接用token单发通知
如果你的目标是给单个设备发送专属通知,完全不需要走主题订阅逻辑。服务端调用FCM发送接口时,直接将目标参数设为对应设备的FCM token即可,这种方式的到达率和实时性都比主题订阅更高。
方案2:确需使用设备专属主题,清洗token生成合法名称
如果业务逻辑必须依赖主题订阅给单设备发通知,只需要把token中的非法字符替换为合法字符即可,参考实现代码如下:
FirebaseMessaging _messaging; Firebase.initializeApp().then((fbr) async { _messaging = FirebaseMessaging.instance; String? token = await _messaging.getToken(); if (token != null) { // 替换所有非法字符为下划线,生成符合规则的主题名 String deviceTopic = token.replaceAll(RegExp(r'[^a-zA-Z0-9_\-\.]'), '_'); await _messaging.subscribeToTopic(deviceTopic); } await _messaging.subscribeToTopic(userID); await _messaging.subscribeToTopic(userTypeId); });
注意:FCM设备token会不定期刷新,你需要额外监听
FirebaseMessaging.instance.onTokenRefresh流,当token更新时,先取消旧token对应的主题订阅,再订阅新token生成的主题,避免设备丢失专属通知。
内容的提问来源于stack exchange,提问作者Hamza Muazzam
相关产品推荐
相关产品推荐

