Cordova-plugin-firebase: (Android)通知をクリックしてもonNotificationOpenコールバックはトリガーされません

作成日 2016年09月21日  ·  28コメント  ·  ソース: arnesson/cordova-plugin-firebase

コルドバ6.3.1
Phonegapfirebaseプラグイン0.1.12
デバイス:Android6.0.1を搭載したLGG5

これは私が使用しているコードです:
`var app = {
//アプリケーションコンストラクタ
初期化:関数(){
this.bindEvents();
}、
//イベントリスナーをバインドします
//
//起動時に必要なイベントをバインドします。 一般的なイベントは次のとおりです。
// 'load'、 'deviceready'、 'offline'、および 'online'。
bindEvents:function(){
document.addEventListener( 'deviceready'、this.onDeviceReady、false);
}、
// devicereadyイベントハンドラ
//
// 'this'のスコープはイベントです。 'receivedEvent'を呼び出すため
//関数、明示的に 'app.receivedEvent(...);'を呼び出す必要があります
onDeviceReady:function(){
console.log( "Estamos en onDeviceReady");
if(navigator.connection.type == Connection.NONE){
navigator.notification.alert( 'インターネットの必要条件');
} それ以外 {
window.FirebasePlugin.onNotificationOpen(function(notification){
console.log(通知);
navigator.notification.alert( "Recibido");
}、function(error){
console.log(エラー);
});
}
}、

};
app.initialize(); `

アプリがバックグラウンド、フォアグラウンド、クローズのすべての状況でシステムのトレイに通知を受け取ります。通知をクリックすると、アプリは3つのケースで開いていますが、コールバックはトリガーされません。

コードに何か問題がありますか?

前もって感謝します。

最も参考になるコメント

onNotificationOpen処理全体を書き直し、期待どおりにほぼ機能するようにしました。これは次のとおりです。

  • 通知は、クライアントがフォアグラウンドで開いている状態で到着し、現在のクライアントでonNotificationOpenが呼び出されます(リロードなし)
  • 通知はクライアントがバックグラウンドで到着し、通知が開かれ、クライアントがフォアグラウンドになり、 onNotificationOpenが現在のクライアントで呼び出されます(リロードなし)

残っているのは、可能であれば(まだ調べていない場合)、通知を開く必要なしにすぐにクライアントに配信することだけです。

私は少しAndroidの初心者なので、改善できる可能性がありますが、問題なく動作しているようですので、共有したいと思いました。

OnNotificationOpe nReceiver:onReceiveは、単に呼び出すようになりました

FirebasePlugin.onBroadcastReceive(context, intent);

FirebasePluginを次のように変更しました

  • callbackContextからWeakReferenceを削除します
  • onBroadcastReceiveメソッドを追加し、インテントデータをonNotificationOpenに渡します
  • onNewIntentメソッドを追加し、インテントデータをonNotificationOpenに渡します
  • onNotificationOpenの古いバージョンを復元し、次のように変更しました

    • WeakReference行を削除しました

    • PluginResultを使用するようにコールバックを変更し、結果に対してsetKeepCallback(true)を呼び出して、最初の呼び出し後にコールバックが削除されないようにします

    private static CallbackContext callbackContext;
    // ...
    private void registerOnNotificationOpen(final CallbackContext callbackContext) {
        FirebasePlugin.callbackContext = callbackContext;
    }

    // called when in foreground
    public static void onBroadcastReceive(Context context, Intent intent) {
        Log.d("FirebasePlugin", "onBroadcastReceive");
        Bundle data = intent.getExtras();
        FirebasePlugin.onNotificationOpen(data);
    }

    // called when in background
    <strong i="32">@Override</strong>
    public void onNewIntent(Intent intent) {
        Log.d(TAG, "new intent " + intent);
        super.onNewIntent(intent);
        FirebasePlugin.onNotificationOpen(intent.getExtras());
    }

    public static void onNotificationOpen(Bundle bundle) {
        if (FirebasePlugin.callbackContext == null ) {
            Log.d("FirebasePlugin", "no callback context, onNotificationOpen ignored");
            return;
        }
        if (callbackContext != null && bundle != null) {
            JSONObject json = new JSONObject();
            Set<String> keys = bundle.keySet();
            for (String key : keys) {
                try {
                    json.put(key, bundle.get(key));
                } catch (JSONException e) {
                    Log.d("FirebasePlugin", "onNotificationOpen: json exception");
                    PluginResult result = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
                    result.setKeepCallback(true);
                    callbackContext.sendPluginResult(result);
                    return;
                }
            }
            Log.d("FirebasePlugin", "onNotificationOpen: send notification to javascript");
            PluginResult result = new PluginResult(PluginResult.Status.OK, json);
            result.setKeepCallback(true);
            callbackContext.sendPluginResult(result);
        }
    }

全てのコメント28件

同じ問題があります。Androidでは通知が届きますが、アプリ内ではコールバックは呼び出されません。
v。0.1.12

@voidbrain @Kibukitaお願いします、リポジトリから最新バージョンをテストしてください。 オープン通知を改善しようとしました。 ありがとう。

@BugsBunnyBRリポジトリの最新バージョンに更新してみて、テストしました。 Androidでは、まだonNotificationOpenを実行していません。

@superheroben 、プラグインコードを呼び出す方法のサンプルをリポジトリに提供できますか? 通知はどのように送信しますか? トピックメッセージでテストしました。

ここでも同じ問題があります。
getInstanceId()コールバックが呼び出され、通知が到着しますが、onNotificationOpen()が呼び出されることはありません。

クライアントコード:

if (window.FirebasePlugin)
{
  window.FirebasePlugin.getInstanceId(
    function(token) {
        thiss.saveToken(token);
    }, 
    function(error) {
        console.log(error);
    }
  );

  window.FirebasePlugin.onNotificationOpen(
    function(notification) {                  
      alert("Yeah!!!");                  
    }, 
    function(error) {
      alert("Error!");
      console.error(error);
    }
  );

  window.FirebasePlugin.grantPermission();
}

私の通知データ構造:

(
    [to] => (device token)
    [notification] => Array
        (
            [title] => Title
            [text] => Test message
            [sound] => default
            [vibrate] => 1
            [badge] => 2
        )
)

私のサーバー側コード(PHP):

$jsonData = json_encode($data);

$ch     = curl_init("https://fcm.googleapis.com/fcm/send");
$header = array(
    'Content-Type: application/json',
    "Authorization: key=".MY_GCM_API_KEY
);

curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, true);
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);

$result = curl_exec($ch);
curl_close($ch);

Cordova Android5.2.2での作業。 テストに使用されたデバイスはAndroid4.4.2を実行します。 プラグインバージョン0.1.12。

@ arivanbastos 、githubリポジトリを

githubからインストールすると、問題が部分的に解決しました。 ありがとう。

cordova plugin remove cordova-plugin-firebase
cordova plugin add https://github.com/arnesson/cordova-plugin-firebase/

これで、アプリがバックグラウンドにあるときにonNotificationOpen()コールバックが呼び出されます。
アプリがフォアグラウンドにある場合、ドキュメントに記載されているのではなく、通知が届き、onNotificationOpen()は呼び出されません。

アプリはフォアグラウンドにあります:
ユーザーは、デバイス自体に通知することなく、JavaScriptコールバックで通知データを受信します(これはプッシュ通知の通常の動作であり、ユーザーに通知するのは開発者の責任です)

「通知」タイプ(データ本文なし)のプッシュを送信する場合、アプリがフォアグラウンドにあるときに通知が表示されないようにする必要があります。

すみません、わかりませんでした。 通知データに「データ」セクションを追加するだけでよいですか?

(
    [to] => (device token)
    [notification] => Array
        (
            [title] => Title
            [text] => Test message
        )
    [data] => Array
        (
            [test] => 1
        )
)

これで問題は解決しませんでした。

「通知」セクションの名前を「データ」に変更すると、通知が到着したときにアプリがクラッシュします(「アプリが停止しました」)。

(
    [to] => (device token)
    [data] => Array
        (
            [title] => Title
            [text] => Test message
        )
)

https://firebase.google.com/docs/cloud-messaging/android/receive
ここでは非常によく説明されています。
通知は、アプリがバックグラウンドにある場合はシステムトレイに送信され、アプリがフォアグラウンドにある場合はonMessageReceived()に送信されます。
メッセージにデータが含まれている場合、これは常にonMessageReceived()に渡されます。

onMessageReceived()の実装に問題があると思います。
私が解釈するコードを見ると、次のようになります。

  • データを抽出する
  • NotificationBuilderを使用して通知を作成する
  • NotificationManagerを介して通知する

NotificationManager.notify(id、notification)は、ステータスバーに表示される通知を投稿します。

ただし、私にとっては、FCMからメッセージを受信するたびに、ステータスバーに通知が表示されることが予想されます。
アプリがフォアグラウンドにあるかどうかのチェックは表示されず、コールバックの呼び出しも表示されません。 私はAndroid開発者ではないので、間違っているかもしれませんが、説明されている動作はそれに適合します。

OK、コールバックを呼び出すコードを見つけました。
BugsBunnyBRからの最後のコミットで、OnNotificationOpenReceiverに変更がありました。これは、arivanbastosがgithubリポジトリをポイントしたときにコールバックを実行することを説明しています。

ただし、それでも、通知は、テキストまたはタイトル(通知またはデータ)がある場合にのみ(OnNotificationOpenReceiverおよびNotificationManagerに)送信されます。 つまり、ステータスバーに表示されるNotificationManagerに通知を送信せずに、アプリにデータを送信することはできません。

@arivanbastos
私はあなたに何か悪いことを言った。 申し訳ありません。
このリポジトリバージョンを指してみましたか?

@packowitz@robertarnesson 。 OK、私の実装は常に*通知を表示しようとします。 または、Firebaseの自動表示通知またはonMessageReceived内のビルドが表示されます。
onNotificationOpenコールバックは、 onMessageReceivedが呼び出されたとき、または通知にデータと通知の本文が同時に含まれているときに呼び出されます。 onNotificationOpenを紹介した私の広報では、通知タイプのプッシュ通知はコールバックを起動しないことを説明しようとしました。 プラグインがコールバックを検出して起動できるように、常にデータ本文と通知本文を含めることをお勧めします。

通知を常に表示することは、Firebaseの標準的な通知動作ではないことを私は知っています。

ほとんどのAndroidアプリ開発者は、アプリがフォアグラウンドにある場合でも、通知がシステムトレイに表示されることを望んでいます。 チャットアプリのように、この動作が良くない場合があることを私は知っています。
Androidの通知機能を開発したとき、チャットアプリのニーズやFirebaseへの準拠については気にしませんでした。

できることは次のとおりです。
1)アプリが開いているときに設定するフラグを作成し、「アプリが開いているときでも通知を表示してほしい」と言って、動作を制御します。 アプリを開くときに常にフラグを設定する場合は、ストレージに保持する必要はありません。

2)この行にコメントを付けて、アプリがフォアグラウンドにあるときの通知を無効にします。

_Always _->プラグインが通知本文に「テキスト」または「タイトル」を見つけた場合。

@BugsBunnyBR動作を選択するためのフラグを設定するというアイデアが好きです。
私はNotificationManagerをOnNotificationOpenReceiverから切り離してJSコールバックをコールバックします。 メッセージにデータが含まれている場合はチェックを導入し、含まれている場合はそのデータを使用してコールバックを呼び出すことをお勧めします。
通知にはフラグを付けるとよいでしょう。
ありがとう。

@BugsBunnyBR githubリポジトリに切り替えるためにテストしたところ、通知をタップすると、アプリが既に実行されている場合でもアプリが再起動することがわかりました。 アプリがフォアグラウンドにあり、通知をタップした場合でも発生します。
しかし、コールバックは現在機能します;)

ここでも同じですが、バージョン0.1.13を使用すると、アプリがフォアグラウンドにあるときにアプリが再起動します。 バージョン0.1.12は正常に機能しています。

リポジトリバージョンでは、通知が適切に機能していません。 その理由は、通知が開かれる前にonNotificationOpenが呼び出された場合、それは無視されると思います。

https://github.com/arnesson/cordova-plugin-firebase/blob/master/src/android/FirebasePlugin.java#L123

registerOnNotificationOpenでは、 notificationBundle待機している場合にのみコールバックを登録します

また、アプリがすでに開いている場合にリロードするように見える理由は、 OnNotificationOpenReceiverに明示的に記載されています

launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

https://github.com/arnesson/cordova-plugin-firebase/blob/master/src/android/OnNotificationOpenReceiver.java#L17

これにより、クライアントは強制的にリロードされ、 onNotificationOpenコールバックが登録されたときにnotificationBundleが使用可能になり、クライアントは通知を受け取ります。

onNotificationOpen処理全体を書き直し、期待どおりにほぼ機能するようにしました。これは次のとおりです。

  • 通知は、クライアントがフォアグラウンドで開いている状態で到着し、現在のクライアントでonNotificationOpenが呼び出されます(リロードなし)
  • 通知はクライアントがバックグラウンドで到着し、通知が開かれ、クライアントがフォアグラウンドになり、 onNotificationOpenが現在のクライアントで呼び出されます(リロードなし)

残っているのは、可能であれば(まだ調べていない場合)、通知を開く必要なしにすぐにクライアントに配信することだけです。

私は少しAndroidの初心者なので、改善できる可能性がありますが、問題なく動作しているようですので、共有したいと思いました。

OnNotificationOpe nReceiver:onReceiveは、単に呼び出すようになりました

FirebasePlugin.onBroadcastReceive(context, intent);

FirebasePluginを次のように変更しました

  • callbackContextからWeakReferenceを削除します
  • onBroadcastReceiveメソッドを追加し、インテントデータをonNotificationOpenに渡します
  • onNewIntentメソッドを追加し、インテントデータをonNotificationOpenに渡します
  • onNotificationOpenの古いバージョンを復元し、次のように変更しました

    • WeakReference行を削除しました

    • PluginResultを使用するようにコールバックを変更し、結果に対してsetKeepCallback(true)を呼び出して、最初の呼び出し後にコールバックが削除されないようにします

    private static CallbackContext callbackContext;
    // ...
    private void registerOnNotificationOpen(final CallbackContext callbackContext) {
        FirebasePlugin.callbackContext = callbackContext;
    }

    // called when in foreground
    public static void onBroadcastReceive(Context context, Intent intent) {
        Log.d("FirebasePlugin", "onBroadcastReceive");
        Bundle data = intent.getExtras();
        FirebasePlugin.onNotificationOpen(data);
    }

    // called when in background
    <strong i="32">@Override</strong>
    public void onNewIntent(Intent intent) {
        Log.d(TAG, "new intent " + intent);
        super.onNewIntent(intent);
        FirebasePlugin.onNotificationOpen(intent.getExtras());
    }

    public static void onNotificationOpen(Bundle bundle) {
        if (FirebasePlugin.callbackContext == null ) {
            Log.d("FirebasePlugin", "no callback context, onNotificationOpen ignored");
            return;
        }
        if (callbackContext != null && bundle != null) {
            JSONObject json = new JSONObject();
            Set<String> keys = bundle.keySet();
            for (String key : keys) {
                try {
                    json.put(key, bundle.get(key));
                } catch (JSONException e) {
                    Log.d("FirebasePlugin", "onNotificationOpen: json exception");
                    PluginResult result = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
                    result.setKeepCallback(true);
                    callbackContext.sendPluginResult(result);
                    return;
                }
            }
            Log.d("FirebasePlugin", "onNotificationOpen: send notification to javascript");
            PluginResult result = new PluginResult(PluginResult.Status.OK, json);
            result.setKeepCallback(true);
            callbackContext.sendPluginResult(result);
        }
    }

うーん...クライアントが実行されていない(強制終了されている)ときに通知が(デバイスに)配信されないことに気づきました。

Firebaseによって提示された通知を直接開いて、動作を確認してみてください。正しい動作であると思われるメインアクティビティが再開されると思います。

遅れて申し訳ありません。 0.1.13で試しましたが、通知が開いた後にアプリが再起動します。

連絡あった ?

0.1.17を使用してAndroidでonNotificationOpenコールバックを成功または失敗させることができません。 ペイロードを使用してAPIまたはGUIを介して送信することはできません。 助言がありますか?

@Mehugeが投稿したコードでプルリクエストを作成しないのはなぜですか?それは私にとってAndroidの魅力のように機能します。

通常の起動インテントを除外するためにFirebasePluginのonNewIntentを更新する必要があったため、onNewIntentコードは次のようになりました。

<strong i="6">@Override</strong>
public void onNewIntent(Intent intent) {
  Log.d(TAG, "new intent " + intent);
  super.onNewIntent(intent);
  Bundle data = intent.getExtras();
  if (data != null) {
    String id = data.getString("id");
    if (null != id) {
      FirebasePlugin.handleNotificationBundle(data);
    } else {
      Log.d(TAG, "Not a notification intent, ignored");
    }
  }
}

私はそれに完全に満足しているわけではありません。 これは、サーバーコードが常に送信するインテントバンドル内のidプロパティを探すことで機能します。 GCMまたはFBMがバンドルに確実に追加して、インテントを通知/メッセージとして識別するために使用できるものはないようです。 一部のGoogleプロパティが追加されることがありますが(トレイから通知を開いている場合)、フォアグラウンドにあるときにクライアントに直接配信されるメッセージと通知の場合、メッセージ内に起動意図であることを示すデータ以外はありません。通知のおかげで、少なくとも私は見ることができました。

これを処理するためのより良い方法がおそらくあります。

@Mehugeは、持っているすべてのファイルで要点を作成して

わかりました、 https://gist.github.com/Mehuge/374ee24d9e18a6c7ccc171d3e521b7adです

ただし、アプリに固有のビットがいくつかあることに注意してください。 コードを大幅に変更していたため、コードをプロジェクトに移動することになりました。 後から考えると、プラグインをフォークしてそのように変更する必要がありましたが、この時点で、予定よりかなり遅れて、すべてにかなりうんざりしていたので、何かを機能させるための最速のルートを取りました。 カスタムビットはかなり明白なので、除外するのは簡単なはずです。

また、プラグインを実装した方法では、クライアントが一時停止されたとき(またはより具体的には一時停止されていないとき)を知る必要があるため、通知を作成するかメッセージを直接配信するかを決定できます。 その機能が必要な場合と不要な場合がありますが、この場合、クライアントがフォアグラウンドにあるときに送信される通知でAndroid通知を作成するのではなく、クライアントに直接配信して処理する必要があります。 クライアントの一時停止状態をプラグインに通知するには、メインアクティビティに次のコードを追加します。

<strong i="9">@Override</strong>
protected void onResume() {
    FirebasePlugin.setPaused(false);
    super.onResume();
}

<strong i="10">@Override</strong>
protected void onPause() {
    FirebasePlugin.setPaused(true);
    super.onPause();
}

対処しなければならない可能性のある別の問題があります。これは、バックグラウンドで通知が届いたが、ユーザーがAndroid通知を開くのではなく、アプリを直接起動した場合に、何らかの方法で対処する必要がある場合があります。 私たちのアプリの場合、未開封の通知をクリアすることができました。 あなたの状況は異なるかもしれません。

最終結果に完全に満足しているわけではありません。たとえば、追加された追加のキーの一部は実験的なものであり、実際には使用されていません。削除することはできません。

フィードバックや提案された改善、または欠陥の指摘に関心があります。 私は特に、通常の打ち上げからGCMペイロードを使用して打ち上げ意図をより適切に検出する方法を見つけることに興味があります。 Googleのプロパティが追加されるのは特定の状況でのみであることがわかりました。 また、さまざまなタイプの通知(is_push、is_notify、broadcast)を検出する試みは実際には機能していません。

#108を参照

私の場合、次のようなリクエストを行うことで解決できます。

{
  "registration_ids": [...tokens],
  "notification" : {
        "title": "Notf title",
        "body": "Notification body"
     },
     "data": {
        "click_action": "/call/dwEugLJ9PTVdcFb064CX"
     }
}

ただし、click_actionをパラメーターとして取得し、手動でリダイレクトする必要がありました(reactアプリでcordovaを使用していました)。

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

JonSmart picture JonSmart  ·  3コメント

rlz picture rlz  ·  4コメント

danielpalen picture danielpalen  ·  5コメント

stephan-nordnes-eriksen picture stephan-nordnes-eriksen  ·  5コメント

michaelreiser picture michaelreiser  ·  5コメント