Drupal发布新内容时如何通过Laravel触发Firebase向所有移动设备推送通知?
实现Drupal发布新内容时自动触发Laravel推送Firebase通知的方案
一、Laravel端适配调整
1. 优化推送逻辑支持全量设备推送
你现有的sendNotification方法仅支持单设备推送,我们新增批量推送方法,利用FCM的registration_ids参数实现单请求最多推送1000台设备,设备量大时自动分批处理:
// 原有单设备推送方法保留,新增全量推送方法 public function sendNotificationToAll($message) { $SERVER_API_KEY = 'myKey'; // 从数据库查询所有有效设备令牌,按需调整表名和字段名 $deviceTokens = \DB::table('devices')->where('is_valid', 1)->pluck('device_token')->toArray(); $responses = []; // FCM单次批量推送最多支持1000个令牌,做分批处理 $tokenChunks = array_chunk($deviceTokens, 1000); $headers = [ 'Authorization: key=' . $SERVER_API_KEY, 'Content-Type: application/json', ]; foreach ($tokenChunks as $chunk) { $data = [ "registration_ids" => $chunk, "notification" => $message ]; $dataString = json_encode($data); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString); $responses[] = curl_exec($ch); curl_close($ch); } return $responses; }
2. 新增供Drupal调用的API接口
添加带身份校验的API路由,避免接口被恶意调用,示例使用自定义API密钥中间件做校验:
首先在routes/api.php中添加路由:
// 全量推送接口,需提前实现api.key中间件,校验请求头X-API-KEY是否和预设密钥一致 Route::post('/push/broadcast', [NotificationController::class, 'broadcast'])->middleware('api.key');
新增控制器处理逻辑:
public function broadcast(Request $request) { // 参数校验 $validated = $request->validate([ 'title' => 'required|string|max:100', 'body' => 'required|string|max:200', 'content_id' => 'nullable|integer' ]); // 组装通知内容 $message = [ 'title' => $validated['title'], 'body' => $validated['body'], 'content_id' => $validated['content_id'] ]; // 执行推送 $result = $this->sendNotificationToAll($message); return response()->json(['status' => 'success', 'data' => $result]); }
二、Drupal端触发逻辑配置
在Drupal自定义模块中实现hook_node_insert钩子,新内容发布成功后自动请求Laravel推送接口:
/** * Implements hook_node_insert(). */ function custom_push_node_insert(\Drupal\node\NodeInterface $node) { // 仅指定内容类型触发推送,示例为文章类型article,按需调整 if ($node->bundle() !== 'article') { return; } // 组装通知参数 $contentBody = $node->hasField('body') ? strip_tags(mb_substr($node->get('body')->value, 0, 80)) . '...' : '点击查看详情'; $pushData = [ 'title' => '新内容发布:' . $node->getTitle(), 'body' => $contentBody, 'content_id' => $node->id() ]; // 发起接口请求 $httpClient = \Drupal::httpClient(); try { $httpClient->post('https://你的Laravel服务域名/api/push/broadcast', [ 'headers' => [ 'X-API-KEY' => '和Laravel端约定的校验密钥', 'Content-Type' => 'application/json' ], 'json' => $pushData ]); \Drupal::logger('custom_push')->info('内容@nid推送成功', ['@nid' => $node->id()]); } catch (\Exception $e) { // 捕获异常不影响内容发布,仅记录错误日志 \Drupal::logger('custom_push')->error('推送失败:' . $e->getMessage()); } }
注意事项
- 可根据业务需求调整Drupal触发推送的内容类型,也可以增加发布状态校验,仅审核通过的内容才触发推送
- 可根据FCM返回的响应结果,定期清理数据库中无效、过期的设备令牌,减少无效请求
- 若推送量级较大,建议在Laravel端引入队列异步处理推送逻辑,避免接口响应超时
- API密钥要妥善保管,不要泄露在前端代码中
内容的提问来源于stack exchange,提问作者Jag
相关产品推荐
相关产品推荐

