質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.92%

Laravel5.1 Androidへのプッシュ通知で400 Bad Requestが出る。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,241

score 13

Androidアプリにプッシュ通知を送りたい

この機能ですが、以前は動いていたはずなのですが、最近エラーを吐いていることを見つけました。
同様な処理をiOSに対しても行っていますが、こちらは問題なく動いています。

現在Laravel5.1を使っており、スマホアプリに対してサーバからプッシュ通知を行っています。
以前は動いていたのですが、最近プッシュ通知でエラーが出ていることを発見

Laravelのログでは以下のようなものが出ています。

 local.ERROR: exception 'Sly\NotificationPusher\Exception\PushException' with message '400 Bad Request; invalid message' in /mnt/home/apache/..../vendor/sly/notification-pusher/src/Sly/NotificationPusher/Adapter/Gcm.php:72


400 Bad Request, invalid messageとあります。

テスト用に簡単なプッシュAPIプログラムを作り、それがAndroidに対してのみ発生していることまではわかりました。
(iOSでは発生しない。)

POSTMANで実行したときのエラー(一部)は次の通りです。

in Gcm.php line 72
at Gcm->push(object(Push)) in PushManager.php line 67
at PushManager->push() in App.php line 34
at App->send(object(Message)) in General.php line 1302
at General::pushNotifyAndroid('テストプッシュメッセージ', array('title' => 'App', 'type' => 'messageType', 'source' => .....

General.php pushNotifyAndroid 

    public static function pushNotifyAndroid( $content, $payload, $tokens =  array(), $badge, $appName ){
        $responses = array();
        $deviceList = array();

        foreach ($tokens as $token ){
            $deviceList[] = PushNotification::Device($token);
        }

        $devices = PushNotification::DeviceCollection($deviceList);

        $message = PushNotification::Message($content,array(
            'badge' => $badge,
            'sound' => 'default',
            'title'        => $appName,
            'largeIcon'    => 'large_icon',
            'smallIcon'    => 'small_icon',
            'payload' => $payload,
            "content_available" => 1,
        ));

        $collection = PushNotification::app('appAndroid')
            ->to($devices)
            ->send($message);

        foreach ($collection->pushManager as $push) {
            $response = $push->getAdapter()->getResponse();
            $responses[] = $response;
        }

        return [
            'response' => $responses,
            'push' => $collection
        ];
    }


POSTMANでのエラーのGeneral.php line 1302が上の$collection = PushNotification::app('appAndroid')....に当たります。

Gcm.php

   public function push(PushInterface $push)
    {
        $client        = $this->getOpenedClient();
        $pushedDevices = new DeviceCollection();
        $tokens        = array_chunk($push->getDevices()->getTokens(), 100);

        foreach ($tokens as $tokensRange) {
            $message = $this->getServiceMessageFromOrigin($tokensRange, $push->getMessage());

            try {
                $this->response = $client->send($message);
            } catch (ServiceRuntimeException $e) {
                throw new PushException($e->getMessage());
            }

            if ((bool) $this->response->getSuccessCount()) {
                foreach ($tokensRange as $token) {
                    $pushedDevices->add($push->getDevices()->get($token));
                }
            }
        }

        return $pushedDevices;
    }


このtryで落ちていると思われます。72行目はcatchでのthrow new....部分です。

どこで落ちているか迄は追えたのですが、この先の解決方法が見つからず困っています。

これだけの情報では解決は難しいと思っています。調査先なども含めて教えていただけると幸いです。
(なにぶんLaravelなどについては初心者ですので、よろしくお願いいたします。)

 その他情報など

以前は問題なく動いていましたが、途中で次のような作業を行っています。

・プッシュ通知の非同期化
このため、一度Laravelのキャッシュをクリアしました。
.envの書き換えも実行
非同期化については成功しています。
 
環境的な大きな変化としてはこれが思い当たります。

今回の不具合の確認では同期、非同期どちらでも同様な問題が起きていることを確認しています。
(結局は同じプログラムが呼ばれている。)
繰り返しになりますが、iOSでは問題なく稼働しています。

その後の調査

前回回答をいただいてから、さらに調査を行いました。
この件、GCM→FCM問題と考え、関連するライブラリのアップデート、エンドポイントの確認(fcmを向いているかどうか)を行いましたが、現象は変わらないようです。
400 Bad request が出ていますが、invalid messageというエラーも出ています。

exception 'Sly\NotificationPusher\Exception\PushException' with message '400 Bad Request; invalid message' in /mnt/home/apache/..../vendor/sly/notification-pusher/src/Sly/NotificationPusher/Adapter/Gcm.php:72


これを読むと、送信時のパラメータなどがおかしいので、リクエスト自体がおかしいと言うようにも読めます。
調べていくと、アプリ側はGCMのままでもプッシュ受信は可能とのことなので、やはり送信時の何かがおかしいと言うことになります。
元のライブラリのGitHubの方にも問合せをしておりますが、そちらはまだ返答無い状況です。

これですが、ライブラリを更新したら、「同期状態」ではエラーは出なくなりました。(プッシュはまだ飛ばない)
現象が変わらないと言うのは「非同期」通知の場合です。
なので、複合要因。
切り分けて、調査します。
まずは、同期状態でプッシュが飛ぶかどうか。(非同期の問題の要因は、おそらくキューワーカーリスタートすれば解決するかと)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

普段はSNSでプッシュするのでGCMの都合はよくわかりませんが

400 Bad Request, invalid message

と言われているという事であれば、APIへのリクエストが正常に行われていない
具体的には、messageが不正、正しくない、nullとか空の可能性がある
または、API自体が仕様変更されたため、パラメータが不足しているという事ではないでしょうか

Sly\NotificationPusher\Exception\PushException

という事なので
https://github.com/Ph3nol/NotificationPusher
Github上でIssue立てた方が早いきがしないでもないです。

(結局は同じプログラムが呼ばれている。)

これについては、非同期(Worker)でやる場合は、Modelが一旦シリアライズされるので
全く同一条件という事ではないかと思います
(今まで何回かデシリアライズでこけた事が何度か、idだけ保存してModelは再度Findしたほうが懸命っぽい)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/09 00:12

    GCMに詳しいわけではありませんが
    現状のエラーや状況をみると、GCM側で受け付けていないような印象です。

    2018年の記事の1年後なのですでに廃止されているのでは・・・?

    キャンセル

  • 2019/08/09 00:35

    はい、それであれば、エラーに納得感(?)があります。
    ありがとうございます。
    おかげさまでかなりわかってきたので、もう少し調べてみます。

    キャンセル

  • 2019/08/12 13:55

    FCM対応のためライブラリをすべて新しいものに更新しましたが、現象は変わらないようです。

    キャンセル

check解決した方法

0

この件、そもそもはプッシュを飛ばしたいので完全に解決はしていませんが、少なくとも400エラーは出なくなったのでクローズします。
→昨日まではそうでしたが、先ほどテストしてみたら、無事にプッシュが飛びました。
(反映するまで時間がかかるということか?)

解決方法としては、関連するライブラリの全更新。
この場合は、
composer update --with-dependencies davibennun/laravel-push-notification
などを実施し、関連する依存ライブラリの更新を行いました。

同期状態でのプッシュテストではとりあえずエラーは消えています。(ただしプッシュは飛んでいません。)

また、非同期の場合は、どうやらキューワーカーのキャッシュの問題があるようなので、一度キューをリスタートし、変更プログラムをリロードする必要があるようです。
こちらも
php artisan queue:restart
で非同期も無事に動くことを確認できました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る