Flutter中OneSignal基于用户推送通知遇问题:无external_user_id方法且调用报错
Flutter中基于OneSignal实现用户定向推送的解决方案
错误原因分析
你遇到的错误是因为postNotificationWithJson是客户端侧方法,但调用OneSignal推送API必须携带REST API密钥做身份验证。直接在客户端调用这个方法不仅需要暴露密钥(严重不安全),而且SDK本身也不推荐这种做法——客户端的核心职责是接收推送和关联用户ID,推送逻辑应该放在后端服务中。
正确实现步骤
1. 客户端绑定External User ID
在Flutter客户端中,将你的业务系统用户ID绑定到OneSignal设备上,完成用户与设备的关联:
// 用户登录成功后调用此方法 await OneSignal.shared.setExternalUserId("123456789");
2. 后端调用OneSignal REST API发送推送
所有推送请求必须由后端发起,以此安全存储和使用REST API密钥。以下是两种实现示例:
示例1:curl命令(快速测试用)
curl --request POST \ --url https://onesignal.com/api/v1/notifications \ --header 'Authorization: Basic 你的REST_API密钥' \ --header 'Content-Type: application/json' \ --data '{ "app_id": "你的OneSignal应用ID", "include_external_user_ids": ["123456789"], "contents": {"en": "test notification"} }'
示例2:Dart后端代码(生产环境用)
如果后端基于Dart/Flutter开发,可使用http包发送请求:
import 'package:http/http.dart' as http; import 'dart:convert'; Future<void> sendUserNotification(String externalUserId) async { const String restApiKey = '你的REST_API密钥'; const String appId = '你的OneSignal应用ID'; final Uri apiUrl = Uri.parse('https://onesignal.com/api/v1/notifications'); final Map<String, String> headers = { 'Authorization': 'Basic $restApiKey', 'Content-Type': 'application/json', }; final Map<String, dynamic> body = { 'app_id': appId, 'include_external_user_ids': [externalUserId], 'contents': {'en': 'test notification'}, }; final http.Response response = await http.post( apiUrl, headers: headers, body: jsonEncode(body), ); if (response.statusCode != 200) { throw Exception('推送失败:${response.body}'); } }
关键注意事项
- 绝对禁止在客户端代码中硬编码REST API密钥:密钥一旦泄露,攻击者可随意调用你的OneSignal API,造成推送滥用或配额消耗。
- 客户端仅需完成用户ID与设备的绑定,推送的触发、内容组装逻辑全部交给后端,既灵活又安全。
内容的提问来源于stack exchange,提问作者Hüseyin Sezen
相关产品推荐
相关产品推荐

