【问题标题】:How can I send a Firebase Cloud Messaging notification without use the Firebase Console?如何在不使用 Firebase 控制台的情况下发送 Firebase 云消息传递通知?
【发布时间】:2016-09-19 05:05:57
【问题描述】:

我开始使用新的 Google 通知服务,Firebase Cloud Messaging

感谢此代码 https://github.com/firebase/quickstart-android/tree/master/messaging,我能够将通知从我的 Firebase 用户控制台发送到我的 Android 设备。

是否有任何 API 或方法可以在不使用 Firebase 控制台的情况下发送通知?我的意思是,例如,一个 PHP API 或类似的东西,直接从我自己的服务器创建通知。

【问题讨论】:

标签: php android firebase firebase-cloud-messaging


【解决方案1】:

Firebase 云消息传递有一个服务器端 API,您可以调用它来发送消息。见https://firebase.google.com/docs/cloud-messaging/server

发送消息可以像使用curl 调用HTTP 端点一样简单。见https://firebase.google.com/docs/cloud-messaging/server#implementing-http-connection-server-protocol

curl -X POST --header "Authorization: key=<API_ACCESS_KEY>" \
    --Header "Content-Type: application/json" \
    https://fcm.googleapis.com/fcm/send \
    -d "{\"to\":\"<YOUR_DEVICE_ID_TOKEN>\",\"notification\":{\"title\":\"Hello\",\"body\":\"Yellow\"}}"

【讨论】:

  • 如何在 iOS 上获取设备 ID?是我们通过 didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData 获得的设备令牌还是我们通过 FIRInstanceID.instanceID().token() 获得的长设备令牌?
  • Frank 我按照 firebase docs 和 codelabs 上的指南在渐进式 web 应用程序上添加推送通知并使用 POstman 发布 http 请求,但我不断收到 401 错误。有什么建议。我直接从我的 firebase 控制台复制我的服务器密钥。
  • 如何发送给所有用户而不是特定用户或主题?
  • 我在早期尝试使用 CURL sn-p 时收到了此错误消息:字段“优先级”必须是 JSON 编号:10。在我从 10 中删除引号后结束,它奏效了。
  • @vinbhai4u 用于发送给所有用户,需要将主题订阅到“所有”主题。所以发送到'/topics/all'
【解决方案2】:

正如 Frank 所提到的,您可以使用 Firebase Cloud Messaging (FCM) HTTP API 从您自己的后端触发推送通知。但你将无法

  1. 向 Firebase 用户标识符 (UID) 和
  2. 发送通知
  3. 向用户群发送通知(您可以在用户控制台上定位属性和事件)。

含义:您必须自己存储 FCM/GCM 注册 ID(推送令牌)或使用 FCM 主题订阅用户。另请注意,FCM 不是 Firebase 通知 API,它是一个较低级别的 API,没有调度或开放率分析。 Firebase 通知建立在 FCM 之上。

【讨论】:

    【解决方案3】:

    例如,您可以将 PHP 脚本用于 Google Cloud Messaging (GCM)。 Firebase 及其控制台位于 GCM 之上。

    我在 github 上找到了这个: https://gist.github.com/prime31/5675017

    提示:此 PHP 脚本生成 android notification

    因此:如果您想在 Android 中接收和显示通知,请阅读 this answer from Koot

    【讨论】:

      【解决方案4】:

      使用服务 api。

      网址:https://fcm.googleapis.com/fcm/send

      方法类型:POST

      标题:

      Content-Type: application/json
      Authorization: key=your api key
      

      身体/有效载荷:

      {
         "notification": {
            "title": "Your Title",
            "text": "Your Text",
            "click_action": "OPEN_ACTIVITY_1"
         },
         "data": {
            "<some_key>": "<some_value>"
         },
         "to": "<device_token>"
      }
      

      在您的应用程序中,您可以在要调用的活动中添加以下代码:

      <intent-filter>
          <action android:name="OPEN_ACTIVITY_1" />
          <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
      

      也可以在Firebase onMessageReceived not called when app in background上查看答案

      【讨论】:

      • Ankit,我可以发送到特定的设备ID。但是,我无法发送给所有人。我必须放什么 "to" : "to_id(firebase refreshedToken)" 而不是设备 ID? "all" 根本不工作。我正在使用 C# WebRequest 发送通知。 @AshikurRahman 你的建议也欢迎。自 3-4 天以来,我一直在苦苦寻找。
      • 没关系。我找到了解决方案。 to : "/topics/all" 将向所有设备发送通知,或者如果您只想针对 IOS 将 all 替换为 ios,对于 android,请替换为 `android'。这些是默认主题集。我猜。
      • 阅读这篇博文了解更多详情 -> developine.com/…
      • @Ankit,您好,您能指定如何获取目标设备的 id 吗?
      【解决方案5】:

      首先您需要从 android 获取一个令牌,然后您可以调用此 php 代码,您甚至可以发送数据以在您的应用中进行进一步的操作。

       <?php
      
      // Call .php?Action=M&t=title&m=message&r=token
      $action=$_GET["Action"];
      
      
      switch ($action) {
          Case "M":
               $r=$_GET["r"];
              $t=$_GET["t"];
              $m=$_GET["m"];
      
              $j=json_decode(notify($r, $t, $m));
      
              $succ=0;
              $fail=0;
      
              $succ=$j->{'success'};
              $fail=$j->{'failure'};
      
              print "Success: " . $succ . "<br>";
              print "Fail   : " . $fail . "<br>";
      
              break;
      
      
      default:
              print json_encode ("Error: Function not defined ->" . $action);
      }
      
      function notify ($r, $t, $m)
          {
          // API access key from Google API's Console
              if (!defined('API_ACCESS_KEY')) define( 'API_ACCESS_KEY', 'Insert here' );
              $tokenarray = array($r);
              // prep the bundle
              $msg = array
              (
                  'title'     => $t,
                  'message'     => $m,
                 'MyKey1'       => 'MyData1',
                  'MyKey2'       => 'MyData2', 
      
              );
              $fields = array
              (
                  'registration_ids'     => $tokenarray,
                  'data'            => $msg
              );
      
              $headers = array
              (
                  'Authorization: key=' . API_ACCESS_KEY,
                  'Content-Type: application/json'
              );
      
              $ch = curl_init();
              curl_setopt( $ch,CURLOPT_URL, 'fcm.googleapis.com/fcm/send' );
              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, json_encode( $fields ) );
              $result = curl_exec($ch );
              curl_close( $ch );
              return $result;
          }
      
      
      ?>
      

      【讨论】:

        【解决方案6】:

        使用 curl 的示例

        向特定设备发送消息

        要将消息发送到特定设备,请将 设置为特定应用实例的注册令牌

        curl -H "Content-type: application/json" -H "Authorization:key=<Your Api key>"  -X POST -d '{ "data": { "score": "5x1","time": "15:10"},"to" : "<registration token>"}' https://fcm.googleapis.com/fcm/send
        

        向主题发送消息

        这里的主题是:/topics/foo-bar

        curl -H "Content-type: application/json" -H "Authorization:key=<Your Api key>"  -X POST -d '{ "to": "/topics/foo-bar","data": { "message": "This is a Firebase Cloud Messaging Topic Message!"}}' https://fcm.googleapis.com/fcm/send
        

        向设备组发送消息

        向设备组发送消息与向单个设备发送消息非常相似。将 to 参数设置为设备组的唯一通知键

        curl -H "Content-type: application/json" -H "Authorization:key=<Your Api key>"  -X POST -d '{"to": "<aUniqueKey>","data": {"hello": "This is a Firebase Cloud Messaging Device Group Message!"}}' https://fcm.googleapis.com/fcm/send
        

        使用服务 API 的示例

        API 网址:https://fcm.googleapis.com/fcm/send

        标题

        Content-type: application/json
        Authorization:key=<Your Api key>
        

        请求方法:POST

        请求正文

        给特定设备的消息

        {
          "data": {
            "score": "5x1",
            "time": "15:10"
          },
          "to": "<registration token>"
        }
        

        主题消息

        {
          "to": "/topics/foo-bar",
          "data": {
            "message": "This is a Firebase Cloud Messaging Topic Message!"
          }
        }
        

        向设备组发送消息

        {
          "to": "<aUniqueKey>",
          "data": {
            "hello": "This is a Firebase Cloud Messaging Device Group Message!"
          }
        }
        

        【讨论】:

        • 你在哪里找到端点 url fcm.googleapis.com/fcm/send,它在 firebase 文档中没有提到?
        • 你可以在这个链接中找到firebase.google.com/docs/cloud-messaging/server
        • @J.R.我创建了一个聊天应用程序,当用户向接收者发送消息时,接收者应该收到通知消息。在这种情况下,我该如何使用您的答案?那么我应该给字段“to”的值是什么?
        • @Anad Raj 在我的回答中提到“向特定设备发送消息”
        【解决方案7】:

        这适用于 CURL

        function sendGCM($message, $id) {
        
        
            $url = 'https://fcm.googleapis.com/fcm/send';
        
            $fields = array (
                    'registration_ids' => array (
                            $id
                    ),
                    'data' => array (
                            "message" => $message
                    )
            );
            $fields = json_encode ( $fields );
        
            $headers = array (
                    'Authorization: key=' . "YOUR_KEY_HERE",
                    'Content-Type: application/json'
            );
        
            $ch = curl_init ();
            curl_setopt ( $ch, CURLOPT_URL, $url );
            curl_setopt ( $ch, CURLOPT_POST, true );
            curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
            curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
            curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields );
        
            $result = curl_exec ( $ch );
            echo $result;
            curl_close ( $ch );
        }
        
        ?>
        

        $message 是您要发送到设备的消息

        $id设备注册令牌

        YOUR_KEY_HERE 是您的服务器 API 密钥(或旧服务器 API 密钥)

        【讨论】:

        • Firebase 控制台没有保存推送消息数据到fcm.googleapis.com/fcm/send?
        • 向浏览器发送推送通知,我可以从中获取设备注册 ID?
        • 这很好用,但是由于文本很长,我收到了{"multicast_id":3694931298664346108,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MessageTooBig"}]}。有什么办法可以解决这个问题?
        • @AlishaLamichhane 您的消息是否大于 4096 字节?如果不是,您可以对您的消息进行 base64 编码(文本可能有问题)。如果大于 4096 字节……嗯,这就是 FCM 限制。
        • to 替换 registration_ids
        【解决方案8】:

        如果您想从 android 发送推送通知,请查看我的博文

        Send Push Notifications from 1 android phone to another with out server.

        发送推送通知只不过是对https://fcm.googleapis.com/fcm/send的发布请求

        使用 volley 编码 sn-p:

            JSONObject json = new JSONObject();
         try {
         JSONObject userData=new JSONObject();
         userData.put("title","your title");
         userData.put("body","your body");
        
        json.put("data",userData);
        json.put("to", receiverFirebaseToken);
         }
         catch (JSONException e) {
         e.printStackTrace();
         }
        
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("https://fcm.googleapis.com/fcm/send", json, new Response.Listener<JSONObject>() {
         @Override
         public void onResponse(JSONObject response) {
        
        Log.i("onResponse", "" + response.toString());
         }
         }, new Response.ErrorListener() {
         @Override
         public void onErrorResponse(VolleyError error) {
        
        }
         }) {
         @Override
         public Map<String, String> getHeaders() throws AuthFailureError {
        
        Map<String, String> params = new HashMap<String, String>();
         params.put("Authorizationey=" + SERVER_API_KEY);
         params.put("Content-Typepplication/json");
         return params;
         }
         };
         MySingleton.getInstance(context).addToRequestQueue(jsonObjectRequest);
        

        我建议大家查看我的博客文章以获取完整的详细信息。

        【讨论】:

        【解决方案9】:

        可以使用 FCM HTTP v1 API 端点将通知或数据消息发送到基于 Firebase 的云消息服务器。 https://fcm.googleapis.com/v1/projects/zoftino-stores/messages:send.

        您需要使用 Firebase 控制台生成和下载服务帐户的私钥,并使用 google api 客户端库生成访问密钥。使用任何 http 库将消息发布到上述端点,下面的代码显示使用 OkHTTP 发布消息。你可以在firebase cloud messaging and sending messages to multiple clients using fcm topic example找到完整的服务器端和客户端代码

        如果需要发送特定的客户端消息,需要获取客户端的firebase注册密钥,见sending client or device specific messages to FCM server example

        String SCOPE = "https://www.googleapis.com/auth/firebase.messaging";
        String FCM_ENDPOINT
             = "https://fcm.googleapis.com/v1/projects/zoftino-stores/messages:send";
        
        GoogleCredential googleCredential = GoogleCredential
            .fromStream(new FileInputStream("firebase-private-key.json"))
            .createScoped(Arrays.asList(SCOPE));
        googleCredential.refreshToken();
        String token = googleCredential.getAccessToken();
        
        
        
        final MediaType mediaType = MediaType.parse("application/json");
        
        OkHttpClient httpClient = new OkHttpClient();
        
        Request request = new Request.Builder()
            .url(FCM_ENDPOINT)
            .addHeader("Content-Type", "application/json; UTF-8")
            .addHeader("Authorization", "Bearer " + token)
            .post(RequestBody.create(mediaType, jsonMessage))
            .build();
        
        
        Response response = httpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            log.info("Message sent to FCM server");
        }
        

        【讨论】:

        【解决方案10】:

        使用 Firebase 控制台,您可以根据应用程序包向所有用户发送消息。但使用 CURL 或 PHP API 则不可能。

        通过 API 您可以向特定设备 ID 或订阅用户发送通知到选定主题或订阅主题用户。

        Get a view on following link. It will help you.
        https://firebase.google.com/docs/cloud-messaging/send-message
        

        【讨论】:

          【解决方案11】:

          或者您可以使用 Firebase 云功能,这对我来说是实现推送通知的更简单方法。 firebase/functions-samples

          【讨论】:

          • 我同意...但很遗憾,由于需要先创建一个结算帐户,我们无法再使用它。你认为我可以从我的个人 nodeJs 服务器调用相同的代码吗?
          【解决方案12】:

          如果您使用的是 PHP,我建议您使用 PHP SDK for Firebase:Firebase Admin SDK。您可以按照以下步骤进行简单的配置:

          从 Firebase (Initialize the sdk) 获取项目凭据 json 文件并将其包含在您的项目中。

          在您的项目中安装 SDK。我使用作曲家:

          composer require kreait/firebase-php ^4.35
          

          尝试 SDK 文档中 Cloud Messaging session 中的任何示例:

          use Kreait\Firebase;
          use Kreait\Firebase\Messaging\CloudMessage;
          
          $messaging = (new Firebase\Factory())
          ->withServiceAccount('/path/to/firebase_credentials.json')
          ->createMessaging();
          
          $message = CloudMessage::withTarget(/* see sections below */)
              ->withNotification(Notification::create('Title', 'Body'))
              ->withData(['key' => 'value']);
          
          $messaging->send($message);
          

          【讨论】:

            【解决方案13】:

            this link 的这个解决方案对我帮助很大。你可以去看看。

            带有这些指令的 curl.php 文件可以工作。

            <?php 
            // Server key from Firebase Console define( 'API_ACCESS_KEY', 'AAAA----FE6F' );
            $data = array("to" => "cNf2---6Vs9", "notification" => array( "title" => "Shareurcodes.com", "body" => "A Code Sharing Blog!","icon" => "icon.png", "click_action" => "http://shareurcodes.com"));
            $data_string = json_encode($data);
            echo "The Json Data : ".$data_string;
            $headers = array ( 'Authorization: key=' . API_ACCESS_KEY, 'Content-Type: application/json' );
            $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_RETURNTRANSFER, true );
            curl_setopt( $ch,CURLOPT_POSTFIELDS, $data_string);
            $result = curl_exec($ch);
            curl_close ($ch);
            echo "<p>&nbsp;</p>";
            echo "The Result : ".$result;
            

            记住you need to execute curl.php file using another browser ie not from the browser that is used to get the user token. You can see notification only if you are browsing another website.

            【讨论】:

              【解决方案14】:
              Go to cloud Messaging select:  Server key
              
              
              
              function sendGCM($message, $deviceToken) {
              
                  $url = 'https://fcm.googleapis.com/fcm/send';
                  $fields = array (
                          'registration_ids' => array (
                              $id
                          ),
                          'data' => array (
                              "title" =>  "Notification title",
                              "body" =>  $message,
                          )
                  );
                  $fields = json_encode ( $fields );
                  $headers = array (
                      'Authorization: key=' . "YOUR_SERVER_KEY",
                      'Content-Type: application/json'
                  );
                  $ch = curl_init ();
                  curl_setopt ( $ch, CURLOPT_URL, $url );
                  curl_setopt ( $ch, CURLOPT_POST, true );
                  curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
                  curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
                  curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields );
                  $result = curl_exec ( $ch );
                  echo $result;
              
                  curl_close ($ch);
              }
              

              【讨论】:

              • 替换这一行:'data' => array ( with 'notification' => array (
              【解决方案15】:

              2020 年工作

              $response = Http::withHeaders([
                          'Content-Type' => 'application/json',
                          'Authorization'=> 'key='. $token,
                      ])->post($url, [
                          'notification' => [
                              'body' => $request->summary,
                              'title' => $request->title,
                              'image' => 'http://'.request()->getHttpHost().$path,
                              
                          ],
                          'priority'=> 'high',
                          'data' => [
                              'click_action'=> 'FLUTTER_NOTIFICATION_CLICK',
                              
                              'status'=> 'done',
                              
                          ],
                          'to' => '/topics/all'
                      ]);
              

              【讨论】:

              • 2021 年也可以使用。谢谢。我使用的是“文本”而不​​是“正文”
              【解决方案16】:

              这是我的项目中使用 CURL 的工作代码。

              <?PHP
              
              // API access key from Google API's Console
              ( 'API_ACCESS_KEY', 'YOUR-API-ACCESS-KEY-GOES-HERE' );
              
              
               $registrationIds = array( $_GET['id'] );
              
                // prep the bundle
               $msg = array
               (
                 'message'    => 'here is a message. message',
                  'title'     => 'This is a title. title',
                  'subtitle'  => 'This is a subtitle. subtitle',
                  'tickerText'    => 'Ticker text here...Ticker text here...Ticker text here',
                  'vibrate'   => 1,
                  'sound'     => 1,
                  'largeIcon' => 'large_icon',
                  'smallIcon' => 'small_icon'
               );
              
               $fields = array
               (
                  // use this to method if want to send to topics
                  // 'to' => 'topics/all'
                  'registration_ids'  => $registrationIds,
                   'data'         => $msg
               );
              
               $headers = array
               (
                  'Authorization: key=' . API_ACCESS_KEY,
                  'Content-Type: application/json'
               );
              
               $ch = curl_init();
               curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' );
               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, json_encode( $fields ) );
               $result = curl_exec($ch );
               curl_close( $ch );
              
               echo $result;
              

              【讨论】:

              【解决方案17】:

              简介

              我汇总了上面的大部分答案,并根据 FCM HTTP Connection Docs 更新了变量,以策划一个在 2021 年与 FCM 一起使用的解决方案。感谢 Hamzah Malik 他在上面非常有见地的回答。

              先决条件

              首先,确保您已将您的项目与 Firebase 相关联,并且您已在您的应用上设置了所有依赖项。如果还没有,请先前往FCM Config docs

              如果这样做了,您还需要从 API 复制项目的服务器响应密钥。前往您的Firebase Console,点击您正在处理的项目,然后导航到;

              Project Settings(Setting wheel on upper left corner) -> Cloud Messaging Tab -> Copy the Server key
              

              配置您的 PHP 后端

              我用 Ankit Adlakha's API call structure 和 FCM Docs 编译了 Hamzah 的答案,以提出以下 PHP 函数:

              function sendGCM() {
                // FCM API Url
                $url = 'https://fcm.googleapis.com/fcm/send';
              
                // Put your Server Response Key here
                $apiKey = "YOUR SERVER RESPONSE KEY HERE";
              
                // Compile headers in one variable
                $headers = array (
                  'Authorization:key=' . $apiKey,
                  'Content-Type:application/json'
                );
              
                // Add notification content to a variable for easy reference
                $notifData = [
                  'title' => "Test Title",
                  'body' => "Test notification body",
                  'click_action' => "android.intent.action.MAIN"
                ];
              
                // Create the api body
                $apiBody = [
                  'notification' => $notifData,
                  'data' => $notifData,
                  "time_to_live" => "600" // Optional
                  'to' => '/topics/mytargettopic' // Replace 'mytargettopic' with your intended notification audience
                ];
              
                // Initialize curl with the prepared headers and body
                $ch = curl_init();
                curl_setopt ($ch, CURLOPT_URL, $url );
                curl_setopt ($ch, CURLOPT_POST, true );
                curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
                curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
                curl_setopt ($ch, CURLOPT_POSTFIELDS, json_encode($apiBody));
              
                // Execute call and save result
                $result = curl_exec ( $ch );
              
                // Close curl after call
                curl_close ( $ch );
              
                return $result;
              }
              

              自定义您的通知推送

              要通过令牌提交通知,请使用'to' =&gt; 'registration token'

              会发生什么

              我在我的网站后端设置了该功能,并在 Postman 上对其进行了测试。如果您的配置成功,您应该会收到类似于以下的响应;

              {"message":"{"message_id":3061657653031348530}"}
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2020-06-28
                • 2019-01-26
                • 2016-09-22
                • 2020-04-23
                • 2018-04-11
                • 1970-01-01
                • 1970-01-01
                • 2019-12-30
                相关资源
                最近更新 更多