{"id":2027,"date":"2023-04-01T20:05:20","date_gmt":"2023-04-01T12:05:20","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=2027"},"modified":"2023-04-07T06:14:11","modified_gmt":"2023-04-06T22:14:11","slug":"implementation-of-firebase-push-notification-server","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/04\/01\/implementation-of-firebase-push-notification-server\/","title":{"rendered":"Firebase\u63a8\u9001\u901a\u77e5\u670d\u52a1\u7aef\u5b9e\u73b0"},"content":{"rendered":"<h2>Firebase\u63a7\u5236\u53f0\u914d\u7f6e<\/h2>\n<p>Firebase\u540e\u53f0\u521b\u5efa\u9879\u76ee\uff0c\u83b7\u53d6\u76f8\u5173\u53c2\u6570\u548c\u914d\u7f6e\u5982\u4e0b<\/p>\n<p>\uff081\uff09\u70b9\u51fbProject Overview -&gt; \u9879\u76ee\u8bbe\u7f6e -&gt; \u4e91\u6d88\u606f\u4f20\u9012 \u4e2d\u83b7\u53d6\u670d\u52a1\u5668\u5bc6\u94a5\uff08\u5efa\u8bae\uff0c\u5f53\u7136\u65e7\u7248\u670d\u52a1\u5668\u5bc6\u94a5\u4e5f\u53ef\u4ee5\u4f7f\u7528\uff09 <\/p>\n<p><!-- more --><\/p>\n<p>\uff082\uff09\u670d\u52a1\u8d26\u53f7 -&gt; \u70b9\u51fb\u751f\u6210\u65b0\u7684\u79c1\u94a5\uff0c\u83b7\u53d6\u79c1\u94a5\u914d\u7f6e\uff08json\u6587\u4ef6\uff0c\u4e22\u5931\u540e\u53ef\u4ee5\u91cd\u65b0\u751f\u6210\uff0c\u91cd\u65b0\u751f\u6210\u540e\u9700\u8981\u66ff\u6362\u65e7\u7684\u914d\u7f6e\uff09 <\/p>\n<p>\uff083\uff09Database -&gt; \u4ee5\u6d4b\u8bd5\u6a21\u5f0f\u521b\u5efa\u6570\u636e\u5e93 -&gt; \u9009\u62e9 Realtime Database \u83b7\u5f97\u6570\u636e\u5e93url<\/p>\n<h2>\u53d1\u9001\u63a8\u9001\u901a\u77e5<\/h2>\n<p>\u53c2\u8003\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/fcm.googleapis.com\/fcm\/send\">https:\/\/fcm.googleapis.com\/fcm\/send<\/a><\/p>\n<p>\u8981\u53d1\u9001\u6d88\u606f\uff0c\u5e94\u7528\u670d\u52a1\u5668\u9700\u53d1\u51faPOST\u8bf7\u6c42\u3002\u4f8b\u5982\uff1a<\/p>\n<p>\u8bf7\u6c42\u5730\u5740\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/fcm.googleapis.com\/fcm\/send\">https:\/\/fcm.googleapis.com\/fcm\/send<\/a><\/p>\n<p>HTTP\u8bf7\u6c42\u5934\u5fc5\u987b\u5305\u542b\uff1a<\/p>\n<pre><code>Authorization: key=YOUR_SERVER_KEY\nContent-Type:\u00a0application\/json \u6216 application\/x-www-form-urlencoded;charset=UTF-8(\u7eaf\u6587\u672c\u683c\u5f0f)\u3002\u5982\u679c\u7701\u7565Content-Type\uff0c\u5373\u89c6\u4e3a\u7eaf\u6587\u672c\u683c\u5f0f<\/code><\/pre>\n<p>HTTP \u6b63\u6587\u5185\u5bb9\u53d6\u51b3\u4e8e\u60a8\u4f7f\u7528\u7684\u662f JSON \u8fd8\u662f\u7eaf\u6587\u672c\u3002\u6709\u5173 JSON \u6216\u7eaf\u6587\u672c\u6d88\u606f\u4e2d\u53ef\u80fd\u5305\u542b\u7684\u6240\u6709\u53c2\u6570\u5217\u8868\uff0c\u8bf7\u53c2\u9605\u670d\u52a1\u5668\u53c2\u8003\u3002<br \/>\n<a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/firebase.google.com\/docs\/cloud-messaging\/http-server-ref?hl=zh-cn#params\">https:\/\/firebase.google.com\/docs\/cloud-messaging\/http-server-ref?hl=zh-cn#params<\/a><\/p>\n<blockquote>\n<p>(1) \u53ef\u4ee5\u4f7f\u7528to\u5355\u4e2a\u63a8\u9001\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528registration_ids\u6279\u91cf\u53d1\u9001\uff0c\u4f46\u662f\u505a\u591a1000\u4e2atoken<br \/>\n(2) \u7ed9\u591a\u4e2a\u4eba\u63a8\uff0c\u6709\u4e24\u79cd\uff1a\u4e00\u79cd\u662f\u7ed9\u7ec4\u63a8\uff0c\u4e00\u79cd\u662f\u7ed9\u4e3b\u9898\u63a8<\/p>\n<\/blockquote>\n<h2>Node.js\u5b9e\u73b0<\/h2>\n<pre><code># node install firebase\n# node install request\n# node fcm.js<\/code><\/pre>\n<pre><code class=\"language-javascript\">var firebase = require(&#039;firebase&#039;);\nvar request = require(&#039;request&#039;);\n\nvar API_KEY = &#039;AAAA8mBttg8:APA91bFv9xob7x7-lBRqDwYdd1IbR5DcqUUmQE8t_cWKJSA5WjNbbp0jOWpCCHnarD2JV3MGyqEM3DfQGd8Kvt5swlGJlGqRoPGFPaSrNn44ZzLLz-HotPRzd08koeJf5bshdPzxKoq1&#039;;\n\nvar token = &#039;chPUpTJMeS8:APA91bGlo27OQVskyiqlXvDQGulrIFi9iIpowsjsrKe-0k5rilbjfB3WADSzujtZH3u-HEPcNMZiHZd7j8-CpXauLY39-u8m9kllLxOOo9Ja1LFAtmSB3vXKhiJAwQC31BlhSqILvSqb&#039;;\n\nfirebase.initializeApp({\n    serviceAccount: &quot;pandadeal-firebase-push.json&quot;,\n    databaseURL: &quot;https:\/\/panda-deal-ios.firebaseio.com\/&quot;\n});\n\nvar payload = {\n    \/\/to: token,\n    to: &#039;\/topics\/activity&#039;,\n    notification: {\n        body: &quot;\u901a\u77e5\u5185\u5bb9&quot;,\n        title: &quot;Firebase Cloud Message&quot;,\n        data: {&#039;type&#039;: &#039;test&#039;, &#039;path&#039;: &#039;\/home&#039;}\n    }\n}\n\nsetTimeout(function (args) {\n    sendNotificationToUser(payload);\n}, 200);\n\nfunction sendNotificationToUser(message, onSuccess) {\n    request({\n        url: &#039;https:\/\/fcm.googleapis.com\/fcm\/send&#039;,\n        method: &#039;POST&#039;,\n        headers: {\n            &#039;Content-Type&#039; : &#039;application\/json&#039;,\n            &#039;Authorization&#039;: &#039;key=&#039; + API_KEY\n        },\n        body: JSON.stringify(message)\n    }, function(error, response, body) {\n        if (error) {\n            console.log(&#039;---message send error---&#039;, error);\n        }\n        else if (response.statusCode &gt;= 400) {\n            console.log(&#039;HTTP Error: &#039; + response.statusCode + &#039; - &#039; + response.statusMessage);\n        }\n        else {\n            console.log(body)\n            console.log(&#039;---message send success---&#039;)\n            onSuccess &amp;&amp; onSuccess();\n        }\n    });\n}<\/code><\/pre>\n<h2>Java\u5b9e\u73b0<\/h2>\n<pre><code class=\"language-java\">public class TestFireBase {\n\n    public final static String AUTH_KEY_FCM= &quot;&quot;; \/\/App\u670d\u52a1\u5bc6\u94a5\n\n    public final static String API_URL_FCM = &quot;https:\/\/fcm.googleapis.com\/fcm\/send&quot;; \/\/\u8c37\u6b4c\u63a8\u9001\u5730\u5740\n\n    public static void main(String[] args) {\n        pushFCMNotification();\n    }\n\n    public static void pushFCMNotification() {\n        try {\n            URL url = new URL(API_URL_FCM);\n            HttpURLConnection conn = (HttpURLConnection) url.openConnection();\n            conn.setUseCaches(false);\n            conn.setDoInput(true);\n            conn.setDoOutput(true);\n            conn.setRequestMethod(&quot;POST&quot;);    \n            conn.setRequestProperty(&quot;Authorization&quot;, &quot;key=&quot;+AUTH_KEY_FCM);\n            conn.setRequestProperty(&quot;Content-Type&quot;, &quot;application\/json&quot;); \/\/\u4e0d\u8bbe\u7f6e\u9ed8\u8ba4\u53d1\u9001\u6587\u672c\u683c\u5f0f\n            JSONObject json = new JSONObject();\n            json.put(&quot;to&quot;, &quot;App Token&quot;); \/\/\u5355\u4e00\u63a8\u9001\n            \/\/json.put(&quot;registration_ids&quot;, tokens); \/\/\u6279\u91cf\u63a8\u9001\uff0c\u6700\u591a1000\u4e2atoken\uff0c\u6b64\u5904\u7684tokens\u662f\u4e00\u4e2atoken JSONArray\u6570\u7ec4\n            JSONObject info = new JSONObject();\n            info.put(&quot;title&quot;, &quot;Notification Tilte&quot;);\n            info.put(&quot;body&quot;, &quot;Hello Test Notification&quot;);\n            info.put(&quot;icon&quot;, &quot;myicon&quot;);\n            json.put(&quot;notification&quot;, info); \/\/json\u8fd8\u53ef\u4ee5put\u5176\u4ed6\u53c2\u6570\n\n            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());\n            wr.write(json.toString());\n            wr.flush();\n            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));\n            String line = null;\n            while ((line = reader.readLine())!= null) {\n                System.out.println(line);\n            }\n            wr.close();\n            reader.close();\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n}<\/code><\/pre>\n<h2>PHP\u5b9e\u73b0<\/h2>\n<pre><code class=\"language-php\">namespace App\\Http\\Controllers;\n\nuse App\\Http\\Controllers\\Controller;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\DB;\n\nuse cn\\appblog\\fcm\\Client;\nuse cn\\appblog\\fcm\\Message;\nuse cn\\appblog\\fcm\\Recipient\\Device;\nuse cn\\appblog\\fcm\\Notification;\n\nclass FcmController extends Controller {\n\n    private $apikey;\n    public function __construct()\n    {\n        $this-&gt;apikey = &#039;API_KEY&#039;;\n    }\n\n    \/\/\u7528Fcm\u63a8\u9001\u6d88\u606f\n    public function push($content=&#039;&#039;, $fcmtoken=&#039;&#039;)\n    {\n        $apiKey = $this-&gt;apikey;\n        $client = new Client();\n        $client-&gt;setApiKey($apiKey);\n        $client-&gt;injectHttpClient(new \\GuzzleHttp\\Client());\n\n        \/\/$note = new Notification(&#039;test title&#039;, &#039;\u73b0\u5728\u65f6\u95f4\u662f &#039;.date(&#039;Y-m-d H:i:s&#039;));\n        $note = new Notification(&#039;&#039;, $content);\n        $note-&gt;setIcon(&#039;smile&#039;)\n            -&gt;setColor(&#039;#ffffff&#039;)\n            -&gt;setBadge(1);\n\n        $message = new Message();\n        $message-&gt;addRecipient(new Device($fcmtoken));\n        $message-&gt;setNotification($note)\n            -&gt;setData(array(&#039;someId&#039; =&gt; 11112));\n        $message-&gt;setNotification($note);\n\n        $response = $client-&gt;send($message);\n        var_dump($response-&gt;getStatusCode());\n    }\n\n    \/**\n     * @param array $requestData\n     * @return bool\n     *\/\n    public function old_insertIntoGroup($requestData=[])\n    {\n        if(!$requestData[&#039;tuid&#039;] || !$requestData[&#039;version&#039;] || !$requestData[&#039;fcmtoken&#039;]) {\n            return false;\n        }\n\n        \/\/\u521b\u5efa\u548c\u6dfb\u52a0\u8bbe\u5907\u7ec4\u7684url\n        $url = &#039;https:\/\/android.googleapis.com\/gcm\/notification&#039;;\n\n        $header = [\n            &#039;Content-Type:application\/json&#039;,\n            &#039;Authorization:key = &#039;.$this-&gt;apikey,\n            &#039;project_id: \u9879\u76eeid&#039;,\n        ];\n        $groupkey = &#039;&#039;;\n        \/\/\u5148\u67e5\u627e\u8868\u4e2d\u6700\u8fd1\u65b0\u7684\u8bbe\u5907\u7ec4\u7684key\uff0c\u82e5key\u91cc\u9762\u7684\u5b50\u8d26\u53f7\u5df2\u7ecf\u8fbe\u5230\u4e00\u5b9a\u6570\u76ee\uff0c\u5c31\u65b0\u5efa\u4e00\u4e2a\u7ec4\n        $gdata=DB::select(&#039;select count(id) num,groupkey from zeai_andro_push group by groupkey order by id desc limit 1;&#039;);\n        \/\/$gdata=DB::select(&#039;select groupkey from zeai_andro_push order by id desc limit 1;&#039;);\n\n        \/\/\u786e\u4fdd\u80fd\u6709\u63a8\u9001fcmtoken\n        if(!DB::table(&#039;zeai_andro_push&#039;)-&gt;where([&#039;tuid&#039;=&gt;$requestData[&#039;tuid&#039;]])-&gt;count([&#039;id&#039;])) {\n            $requestData[&#039;groupkey&#039;] = $gdata[0]-&gt;groupkey;\n            DB::table(&#039;zeai_andro_push&#039;)-&gt;insertGetId($requestData);\n        }\n        $groupkey=$gdata[0]-&gt;groupkey;\n        $data = [\n            &quot;operation&quot;=&gt;&quot;add&quot;,\n            &quot;notification_key_name&quot;=&gt; &quot;appUser-Chris&quot;, \/\/\u8bbe\u5907\u7ec4\u540d\n            &quot;notification_key&quot;=&gt;$groupkey,\n            &quot;registration_ids&quot;=&gt;[$requestData[&#039;fcmtoken&#039;]]\n        ];\n\n        $res = json_decode($this-&gt;http($url, $data, &#039;post&#039;, $header), true);\n        if (isset($res[&#039;notification_key&#039;])) {\n            $res=DB::table(&#039;zeai_andro_push&#039;)\n                -&gt;where([&#039;tuid&#039;=&gt;$requestData[&#039;tuid&#039;]])\n                -&gt;update([\n                    &#039;groupkey&#039;=&gt;$res[&#039;notification_key&#039;]\n                ]);\n            return  $res ? true : false;\n        } else {\n            \/\/\u4e00\u4e2a\u8bbe\u5907\u7ec4\u662f\u5426\u6ee1\u5458\u672a\u80fd\u6d4b\u8bd5\n            return false;\n        }\n    }\n\n    \/**\n     * \u6dfb\u52a0\u7528\u6237\u7684\u4e3b\u9898\uff0c\u4fdd\u5b58\u7528\u6237\u7684fcmtoken\n     * @param array $requestData\n     * @return bool\n     *\/\n    public function insertIntoGroup($requestData=[])\n    {\n        if (!$requestData[&#039;tuid&#039;] || !$requestData[&#039;version&#039;] || !$requestData[&#039;fcmtoken&#039;]) {\n            return false;\n        }\n        $this-&gt;oldmyTopic($requestData[&#039;fcmtoken&#039;]);\n        \/\/\u5148\u67e5\u627e\u8868\u4e2d\u6700\u8fd1\u65b0\u7684\u8bbe\u5907\u7ec4\u7684key,\u82e5key\u91cc\u9762\u7684\u5b50\u8d26\u53f7\u5df2\u7ecf\u8fbe\u5230\u4e00\u5b9a\u6570\u76ee\uff0c\u5c31\u65b0\u5efa\u4e00\u4e2a\u7ec4\n\n        \/\/\u786e\u4fdd\u80fd\u6709\u63a8\u9001fcmtoken\n        if (!DB::table(&#039;zeai_andro_push&#039;)-&gt;where([&#039;tuid&#039;=&gt;$requestData[&#039;tuid&#039;]])-&gt;count([&#039;id&#039;])) {\n            $requestData[&#039;groupkey&#039;] = 0;\n            DB::table(&#039;zeai_andro_push&#039;)-&gt;insertGetId($requestData);\n        }\n    }\n\n    \/\/\u521b\u5efa\u8bbe\u5907\u7ec4\n    public function createGroup($fcmtoken=&#039;&#039;)\n    {\n        \/\/\u521b\u5efa\u548c\u6dfb\u52a0\u8bbe\u5907\u7ec4\u7684 url\n        $url = &#039;https:\/\/android.googleapis.com\/gcm\/notification&#039;;\n        $header = [\n            &#039;Content-Type:application\/json&#039;,\n            &#039;Authorization:key=&#039;.$this-&gt;apikey,\n            &#039;project_id:196236249110&#039;,\n        ];\n        $data = [\n            &quot;operation&quot;=&gt;&quot;create&quot;,\n            &quot;notification_key_name&quot;=&gt; (string)time(),\/\/\u8bbe\u5907\u7ec4\u540d\n            &quot;registration_ids&quot;=&gt;[$fcmtoken]\n        ];\n        $res = json_decode( $this-&gt;http($url, $data, &#039;post&#039;, $header), true);\n        return $res[&#039;notification_key&#039;];\n    }\n\n    \/\/\u5411\u4e3b\u9898\u53d1\u9001\u6d88\u606f\n    public function sendMessageToGroup()\n    {\n        $url = &#039;https:\/\/fcm.googleapis.com\/fcm\/send&#039;;\n        $header = [\n            &#039;Content-Type:application\/json&#039;,\n            &#039;Authorization:key=&#039;.$this-&gt;apikey,\n            &#039;project_id:196236249110&#039;,\n        ];\n        $data = [\n            &#039;to&#039;=&gt;&#039;\/topics\/\u4e3b\u9898\u540d&#039;,\n            &quot;notification&quot;=&gt;[\n                &#039;body&#039;=&gt;&quot;^_^ Come and get the coins.There are a lot of new tasks. ^_^&quot;,\n                &#039;title&#039;=&gt;&#039;&#039;,\n                &#039;icon&#039;=&gt;&#039;myicon&#039;\n            ],\n        ];\n        $res = $this-&gt;http($url,$data,&#039;post&#039;,$header);\n        var_dump($res);\n    }\n\n    \/**\n     * \u83b7\u53d6\u81ea\u5df1\u7684\u4e3b\u9898\u5185\u5bb9\n     *\/\n    private function myTopic($fcmtoken=&#039;&#039;)\n    {\n        $url=&#039;https:\/\/iid.googleapis.com\/iid\/info\/&#039;.$fcmtoken.&#039;?details=true&#039;;\n        $header = [\n            \/\/&#039;Content-Type:application\/json&#039;,\n            &#039;Authorization:key=&#039;.$this-&gt;apikey,\n            &#039;details:true&#039;,\n        ];\n        $res=$this-&gt;http($url, &#039;&#039;, &#039;get&#039;, $header);\n        var_dump($res);\n    }\n\n    \/**\n     * \u7ed9\u81ea\u5df1\u6dfb\u52a0\u4e3b\u9898 wdwdinstagram\n     * @param $fcmtoken\n     *\/\n    private function oldmyTopic($fcmtoken)\n    {\n        $url=&#039;https:\/\/iid.googleapis.com\/iid\/v1\/&#039;.$fcmtoken.&#039;\/rel\/topics\/\u4e3b\u9898\u540d&#039;;\n        $header = [\n            &#039;Content-Type:application\/json&#039;,\n            &#039;Authorization:key=&#039;.$this-&gt;apikey,\n            &#039;Content-Length: 0&#039;,\n        ];\n        $this-&gt;http($url, &#039;&#039;, &#039;post&#039;, $header);\n    }\n}<\/code><\/pre>\n<blockquote>\n<p>\u6ce8\uff1a\u9700\u7ffb\u5899\uff0c\u5426\u5219\u62a5\u9519<code>SERVICE_NOT_AVAILABLE<\/code><\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Firebase\u63a7\u5236\u53f0\u914d\u7f6e Firebase\u540e\u53f0\u521b\u5efa\u9879\u76ee\uff0c\u83b7\u53d6\u76f8\u5173\u53c2\u6570\u548c\u914d\u7f6e\u5982\u4e0b \uff081\uff09\u70b9\u51fbProject O [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[43],"tags":[316],"class_list":["post-2027","post","type-post","status-publish","format-standard","hentry","category-java-basic","tag-firebase"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/2027","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=2027"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/2027\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=2027"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=2027"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=2027"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}