如何在Flutter双应用(管理端/客户端)中基于PHP后端实现无需Firebase的图片上传触发推送通知功能
嘿,这个需求完全可以搞定,不用Firebase也有好几种靠谱的实现思路,我给你拆解一下最实用的几个方案,附上具体的代码片段供你参考:
方案一:WebSocket实时推送(最推荐,实时性拉满)
这个方案是最适合实时场景的,管理端上传完图片后能立刻给客户端发通知,而且全程自己掌控,不用依赖第三方平台。
步骤1:PHP后端搭建WebSocket服务
可以用Workerman或者Swoole这两个PHP异步框架来快速搭建,这里以Workerman为例:
- 首先通过Composer安装依赖:
composer require workerman/workerman - 写一个简单的WebSocket服务端代码,用来监听客户端连接并推送消息:
<?php require_once __DIR__ . '/vendor/autoload.php'; use Workerman\Worker; // 创建WebSocket服务,监听8080端口(可以自己改) $ws_worker = new Worker("websocket://0.0.0.0:8080"); // 启动4个进程处理连接,根据服务器配置调整 $ws_worker->count = 4; // 客户端连接时触发,可以在这里记录客户端信息(比如用户ID) $ws_worker->onConnect = function($connection) { echo "新客户端上线\n"; }; // 自定义推送函数,供图片上传接口调用 function pushToClients($notificationData) { global $ws_worker; // 遍历所有在线客户端,发送通知 foreach($ws_worker->connections as $connection) { $connection->send(json_encode($notificationData)); } } // 启动WebSocket服务 Worker::runAll();
- 然后在你现有的图片上传接口里,当图片上传成功后,调用这个
pushToClients函数,传入通知内容,比如:
// 假设你的上传逻辑完成后得到了图片URL $uploadedImageUrl = 'https://your-server.com/uploads/new.jpg'; // 构造推送数据 $notification = [ 'type' => 'new_image', 'message' => '管理端上传了新图片!', 'image_url' => $uploadedImageUrl ]; // 推送通知 pushToClients($notification);
步骤2:Flutter客户端对接WebSocket并展示本地通知
- 首先在
pubspec.yaml里添加依赖:
dependencies: web_socket_channel: ^2.4.0 flutter_local_notifications: ^16.1.0
- 实现WebSocket连接和本地通知逻辑:
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:web_socket_channel/io.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; // 本地通知服务类 class LocalNotificationService { static final FlutterLocalNotificationsPlugin _plugin = FlutterLocalNotificationsPlugin(); // 初始化通知服务 static Future<void> init() async { const AndroidInitializationSettings androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings settings = InitializationSettings(android: androidSettings); await _plugin.initialize(settings); } // 显示通知 static Future<void> showNotification(String title, String body) async { const AndroidNotificationDetails androidDetails = AndroidNotificationDetails( 'image_upload_notif', '新图片通知', channelDescription: '管理端上传新图片时推送的通知', importance: Importance.max, priority: Priority.high, ); const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails); await _plugin.show(0, title, body, notificationDetails); } } // WebSocket管理类 class WebSocketManager { late IOWebSocketChannel _channel; // 连接WebSocket服务 void connect(String serverUrl) { _channel = IOWebSocketChannel.connect(serverUrl); // 监听推送消息 _channel.stream.listen((message) { final data = jsonDecode(message); if (data['type'] == 'new_image') { // 触发本地通知 LocalNotificationService.showNotification('新图片提醒', data['message']); // 这里还可以更新你的图片列表UI } }); } // 断开连接 void disconnect() { _channel.sink.close(); } } // 主应用初始化 void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化本地通知 await LocalNotificationService.init(); runApp(const MyClientApp()); } class MyClientApp extends StatefulWidget { const MyClientApp({super.key}); @override State<MyClientApp> createState() => _MyClientAppState(); } class _MyClientAppState extends State<MyClientApp> { final WebSocketManager _wsManager = WebSocketManager(); @override void initState() { super.initState(); // 连接你的WebSocket服务地址,替换成实际的服务器IP和端口 _wsManager.connect('ws://your-server-ip:8080'); } @override void dispose() { _wsManager.disconnect(); super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('客户端')), body: const Center(child: Text('等待新图片通知...')), ), ); } }
注意事项
- 要确保WebSocket服务的端口在服务器防火墙里是开放的,客户端能访问到。
- 如果你的App是HTTPS的,需要用
wss://协议,配置SSL证书后使用加密连接。 - 要是需要给特定用户推送,就在客户端连接时发送用户ID,后端保存连接和用户ID的映射,推送时只给对应用户的连接发消息。
- 离线消息的话,可以把未推送的消息存在数据库里,客户端下次上线时拉取。
方案二:轮询(简单粗暴,适合小体量应用)
如果你的用户量不大,实时性要求没那么高,可以用轮询的方式:
- 客户端每隔一段时间(比如30秒)调用PHP后端的接口,查询有没有新上传的图片。
- 后端维护一个图片上传的时间戳或者版本号,客户端每次请求时带上自己最后获取的时间戳,后端对比后返回新的记录。
- 客户端拿到新记录后触发本地通知。
这个方案优点是实现简单,不用维护WebSocket服务,缺点是实时性差,会增加服务器请求量。
方案三:第三方推送服务(非Firebase)
如果不想自己维护推送服务,也可以用非Firebase的第三方平台,比如国内的个推、JPush,或者国外的OneSignal(支持不用Firebase的HTTP API推送):
- 管理端上传图片后,PHP后端调用第三方推送服务的API,发送通知。
- Flutter客户端集成对应的SDK,接收并展示通知。
这个方案省心,但需要依赖第三方平台,而且要注意隐私和合规问题。
内容的提问来源于stack exchange,提问作者G H Prakash




