基于Flutter/PHP/MySQL实现数据库新增行时向指定用户推送通知
实现Flutter+PHP+MySQL应用的数据库触发推送通知方案
核心流程
当用户标记商品感兴趣时,完整流程如下:
- Flutter端调用PHP接口,向
product_interests表新增记录 - PHP接口完成插入后,查询该商品所有者的FCM推送令牌
- PHP调用FCM API向所有者发送通知
- Flutter端接收并展示通知
第一步:数据库结构准备
确保你的数据库有以下关键字段:
users表:新增fcm_token字段,用于存储用户的FCM推送令牌products表:保留owner_id字段,关联商品所属的用户IDproduct_interests表:包含product_id(关联商品)、user_id(标记兴趣的用户ID)
第二步:PHP后端处理逻辑
在新增兴趣记录的接口中,完成插入后立即触发推送逻辑:
<?php // 假设已完成PDO数据库连接,接收Flutter传递的product_id和user_id $productId = $_POST['product_id']; $userId = $_POST['user_id']; // 1. 插入兴趣记录到数据库 $insertStmt = $pdo->prepare("INSERT INTO product_interests (product_id, user_id, created_at) VALUES (?, ?, NOW())"); $insertStmt->execute([$productId, $userId]); // 2. 查询商品所有者的FCM Token $tokenStmt = $pdo->prepare("SELECT u.fcm_token FROM products p JOIN users u ON p.owner_id = u.id WHERE p.id = ?"); $tokenStmt->execute([$productId]); $ownerToken = $tokenStmt->fetchColumn(); if ($ownerToken) { // 3. 调用FCM API发送通知 $fcmApiUrl = 'https://fcm.googleapis.com/fcm/send'; $headers = [ 'Authorization: key=你的FCM服务器密钥', // 从Firebase控制台获取 'Content-Type: application/json' ]; // 通知内容 $notificationData = [ 'title' => '新的商品关注', 'body' => "用户ID $userId 关注了你的商品", 'sound' => 'default' ]; // 附加数据(用于Flutter端跳转) $extraData = [ 'product_id' => $productId, 'notification_type' => 'interest' ]; $payload = json_encode([ 'to' => $ownerToken, 'notification' => $notificationData, 'data' => $extraData ]); // 发起请求 $ch = curl_init($fcmApiUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); $response = curl_exec($ch); curl_close($ch); // 可选:记录推送日志到数据库或文件 error_log("FCM推送响应: $response"); } // 返回结果给Flutter端 echo json_encode(['status' => 'success']); ?>
第三步:Flutter端配置与通知处理
1. 集成依赖
在pubspec.yaml中添加FCM和本地通知依赖:
dependencies: firebase_core: ^2.15.0 firebase_messaging: ^14.6.0 flutter_local_notifications: ^16.1.0
2. 获取并上传FCM Token
用户登录或应用启动时,获取Token并上传到PHP接口保存:
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:http/http.dart' as http; Future<void> setupFCM(String currentUserId) async { await Firebase.initializeApp(); // 获取初始Token String? token = await FirebaseMessaging.instance.getToken(); if (token != null) { await http.post( Uri.parse('你的PHP保存Token接口地址'), body: {'user_id': currentUserId, 'fcm_token': token} ); } // 监听Token刷新,更新服务器存储 FirebaseMessaging.instance.onTokenRefresh.listen((newToken) { http.post( Uri.parse('你的PHP保存Token接口地址'), body: {'user_id': currentUserId, 'fcm_token': newToken} ); }); }
3. 接收并展示通知
处理前台、后台通知以及通知点击事件:
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin(); void initNotificationHandling(BuildContext context) async { // 初始化本地通知配置 const AndroidInitializationSettings androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initSettings = InitializationSettings(android: androidInit); await _notificationsPlugin.initialize(initSettings); // 处理前台收到的通知 FirebaseMessaging.onMessage.listen((RemoteMessage message) { RemoteNotification? notification = message.notification; AndroidNotification? android = message.notification?.android; if (notification != null && android != null) { _notificationsPlugin.show( notification.hashCode, notification.title, notification.body, NotificationDetails( android: AndroidNotificationDetails( 'product_interest_channel', '商品关注通知', channelDescription: '收到商品关注时的通知', icon: android.smallIcon, ), ), payload: message.data['product_id'], ); } }); // 处理点击通知打开应用的情况 FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { String productId = message.data['product_id']; // 跳转到商品详情页 Navigator.push( context, MaterialPageRoute(builder: (context) => ProductDetailPage(id: productId)), ); }); }
关键注意事项
- FCM密钥管理:服务器密钥要妥善保管,不要暴露在前端代码中
- Token失效处理:如果FCM推送返回无效Token,需要从数据库中移除该Token,等待用户下次登录重新上传
- 权限申请:Android 13+需要申请
POST_NOTIFICATIONS权限,iOS需要在Info.plist中配置推送权限 - 后台推送:Android需要配置Firebase后台消息服务,iOS需要开启推送后台模式
内容的提问来源于stack exchange,提问作者duaboola
相关产品推荐
相关产品推荐

