首页 > 解决方案 > 如果设备令牌不再有效,我想处理从 fcm 生成的异常

问题描述

我面临的问题是,如果设备不再存在,则 fcm 响应包含这样的错误

{
    "message": "Client error: `POST https://fcm.googleapis.com/v1/projects/internationalfriendspusher/messages:send'resulted in a `404 Not Found` response:\n{\n  \"error\": {\n    \"code\": 
404,\n    \"message\": \"Requested entity was not found.\",\n    \"status\": 
\"NOT_FOUND\",\n    \"detail (truncated...)\n",
    "exception": "Kreait\\Firebase\\Exception\\Messaging\\NotFound",
    "file": "/var/www/vhosts/lvps87-230-85- 
   233.dedicated.hosteurope.de/pusherang/MainApp/vendor/kreait/firebase- 
   php/src/Firebase/Exception/MessagingException.php"
}

我实际上在数组中发送具有设备 ID 的批量通知,并在对应令牌的任何设备 ID 不再存在时循环通过它会破坏我的代码,所以我想处理它并继续到下一个设备 ID

我的请求有效载荷

{
    "message": {
    "content":"My Test notification",
    "content_available":"zXCzCzDXs",
    "message_url":"www.example.com",
    "priority":"dfgdfgfd",
    "title":"Test"
    },
    "device_ids":[
    "4706277e9565496",
    "f02f1f4558206539"
    ]
}

代码

foreach($input['device_ids'] as $deviceId)
{
    $pusher = Push::where('device_id' , $deviceId )
                       ->where('push_enable' , 'true')
                       ->first();
    if($pusher)
    {
         if(strtolower($pusher->push_enable)  == "true")
         {
             $deviceToken = $pusher->registration_id;

             $message = CloudMessage::withTarget('token', $deviceToken);

             $title = $input['message']['title'];
             $body = $input['message']['content'];

             $notification = Notification::fromArray([
                   'title' => $title,
                   'body' => $body
             ]);

             $message = $message->withNotification($notification);

             try 
             {
                 // Here notification send to device and here my code breaks if device token not validate or user install app
                 $this->messaging->send($message));     
                 $device = new Device;
                 $device->deviceId = $deviceId;
                 $device->title = $title;
                 $device->content = $body;
                 $device->message_url = $input['message']['message_url'];
                 $device->priority = $input['message']['priority'];
                 $device->content_available = $input['message']['content_available'];
                 $status = $device->save();
                 if($status)
                 {
                    continue;
                 }                                    
            }
            catch(Exception $e) 
           {
              echo "Permission denied for Device: ".$deviceId." having token ".$deviceToken." from Firebase";
                                  continue;
           }
      }
      else
      {
        continue;
      }                                
  }
  else
  {
     echo "Device having id ".$deviceId." were not found";
     continue;
  }
}

标签: laravelfirebase-cloud-messaging

解决方案


你快到了 - 这是一个命名空间问题。

catch(Exception $e),在命名空间文件中(即文件namespace App\Foo\Bar顶部),并没有捕获太多 - 它也是命名空间,所以你只会捕获App\Foo\Bar\Exception.

use Exception别名放在文件顶部将告诉 PHP 使用异常而不是命名空间异常。

或者,catch(\Exception $e)带有前导 \ 的 将做同样的事情。

旁注:您可以以相同的方式捕获特定异常,即:

catch(\Kreait\Firebase\Exception\Messaging\NotFound $e)

推荐阅读