在Android应用中未收到Firebase云推送通知 [英] Not receiving Firebase cloud push notifications in Android app

查看:32
本文介绍了在Android应用中未收到Firebase云推送通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有收到有关我的应用的推送通知.我包括清单文件,MainActivity文件,MyFireBaseMessagingService文件以及build.gradle文件和googl-services.json.我真的对可能出现的问题感到困惑.我去Firebase作曲家写消息,但是什么也没收到.我可以对字符串文件中的值进行硬编码,并且会收到通知,但我想要更动态的东西.这就是为什么我试图弄清楚如何从FCM发送推送通知,但是我似乎丢失了某些内容或输入了错误的内容.

I am not receiving push notification for my app. I have included the manifest files, the MainActivity file, the MyFireBaseMessagingService file and the build.gradle file and the googl-services.json. I really am stumped on what the issue could be. I go to Firebase composer to write message but nothing is received. I can hard code values in strings file and I receive a notification but I wanted something more dynamic. That is why I am trying to figure out how to send push notifications from FCM but I seem to be missing something or inputting something incorrectly.

MainAcitivity文件

MainAcitivity file

package com.example.testaaedapp;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.InstanceIdResult;

import java.net.URI;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private ImageButton logoButton;
    private ImageView blueButton, greenButton, orangeButton, yellowButton, redButton, darkBlueButton;
    public Button callButton;
    private final String CHANNEL_ID = "Alerts";
    private final int notificationId = 001;
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        logoButton = findViewById(R.id.imageButton);
        logoButton.setOnClickListener(this);

        blueButton = findViewById(R.id.bluepuzzlepiece);
        blueButton.setOnClickListener(this);

        redButton = findViewById(R.id.redpuzzlepiece);
        redButton.setOnClickListener(this);

        greenButton = findViewById(R.id.greenpuzzlepiece);
        greenButton.setOnClickListener(this);

        orangeButton = findViewById(R.id.orangepuzzlepiece);
        orangeButton.setOnClickListener(this);

        yellowButton = findViewById(R.id.yellowpuzzlepiece);
        yellowButton.setOnClickListener(this);

        darkBlueButton = findViewById(R.id.darkbluepuzzlepiece);
        darkBlueButton.setOnClickListener(this);

        callButton = findViewById(R.id.button);
        callButton.setOnClickListener(this);

        displayNotification();
        // Get token
        // [START retrieve_current_token]
        FirebaseInstanceId.getInstance().getInstanceId()
                .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
                    @Override
                    public void onComplete(@NonNull Task<InstanceIdResult> task) {
                        if (!task.isSuccessful()) {
                            Log.w(TAG, "getInstanceId failed", task.getException());
                            return;
                        }

                        // Get new Instance ID token
                        String token = task.getResult().getToken();

                        // Log and toast
                        String msg = getString(R.string.msg_token_fmt, token);
                        Log.d(TAG, msg);
                        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                    }
                });
        // [END retrieve_current_token]

    }
        int requestCode = 0;
    public void onClick(View view) {

        if (view.getId() == R.id.button && ActivityCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            Log.d("STATE", "Call Button DOES NOT WORK");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, requestCode);
            return;
        } else if (view.getId() == R.id.button && ActivityCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
//            else if (view.getId() == R.id.button && ActivityCompat.checkSelfPermission(MainActivity.this,
//                    Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
            Log.d("STATE", "Call Button DOES WORK");
            Intent callIntent = new Intent(Intent.ACTION_CALL);
            callIntent.setData(Uri.parse("tel:480-240-9255"));
            startActivity(callIntent);


        } else {
            switch (view.getId()) {
                case R.id.imageButton:
                    setContentView(R.layout.activity_main);
                    break;

                case R.id.bluepuzzlepiece:

                    break;

                case R.id.redpuzzlepiece:
                    Intent blogIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.aaed.org/blog"));
                    startActivity(blogIntent);
                    break;

                case R.id.greenpuzzlepiece:
                    Intent videoIntent = new Intent(Intent.ACTION_VIEW);
                    videoIntent.setData(Uri.parse("https://www.youtube.com/channel/UCUwPShLvnCOTeQILvAtneOw"));
                    startActivity(videoIntent);
                    break;

                case R.id.yellowpuzzlepiece:
                    Intent secondActivity = new Intent(this, SecondActivity.class);
                    startActivity(secondActivity);
                    break;

                case R.id.orangepuzzlepiece:
                    Intent webIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.aaed.org"));
                    startActivity(webIntent);
                    break;

                case R.id.darkbluepuzzlepiece:
                    Intent schoolIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.aaed.org/online-course-content"));
                    startActivity(schoolIntent);


            }

        }

    }

    public void displayNotification () {
        createNotificationChannel();
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_puzzlepieces)
                .setContentTitle("Test Message")
                .setContentText("This is text")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setStyle(new NotificationCompat.BigTextStyle()
                        .bigText(getString((R.string.another_string))));

        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);

        // notificationId is a unique int for each notification that you must define
        notificationManager.notify(notificationId, builder.build());
    }

    public void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.channel_name);
            String description = getString(R.string.channel_description);
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            /

/ Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == requestCode)
        {
            if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                Intent callIntent = new Intent(Intent.ACTION_CALL);
                callIntent.setData(Uri.parse("tel:480-240-9255"));
                startActivity(callIntent);
            }
        }

MyFirebaseMessagingService文件

MyFirebaseMessagingService file

package com.example.testaaedapp;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import androidx.core.app.NotificationCompat;

import com.example.testaaedapp.MainActivity;
import com.example.testaaedapp.R;
import com.google.firebase.messaging.FirebaseMessagingService;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    // [START on_new_token]

    /**
     * Called if InstanceID token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the InstanceID token
     * is initially generated so this is where you would retrieve the token.
     */
    @Override
    public void onNewToken(String token) {
        Log.d(TAG, "Refreshed token: " + token);

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // Instance ID token to your app server.
        sendRegistrationToServer(token);
    }
    // [END on_new_token]

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testaaedapp">

    <!--
         The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but you must specify either coarse or fine
         location permissions for the 'MyLocation' functionality.
    -->
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps"></activity>
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="AAED" />
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/ic_puzzlepieces" />
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/colorAccent" />

        <activity
            android:name=".MainActivity"
            android:label="Autism Academy"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SecondActivity"
            android:label="Locations"></activity>

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />
        <!-- [START firebase_service] -->
        <service
            android:name=".MyFirebaseMessagingService"
            android:exported="false"
            android:enabled="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>


        <!-- [END firebase_service] -->
    </application>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>

</manifest>

推荐答案

我遇到了类似的问题.我已经尝试了一切-我认为主要原因是所有服务迟早都会被系统杀死.唯一的方法是确保将通知传递到系统托盘而不是应用程序.为此,您需要使用数据消息通知.

I've had a similar issue. I've tried everything - in my opinion the main reason is that all the services are, sooner or later, being killed by the system. The only way is to make sure to deliver the notification to the system tray not to the application. To do that you need to use Data message notifications.

FCM通知有2种类型:通知消息和数据消息.

There are 2 types of FCM notifications: Notification message and Data message.

数据消息传递到系统托盘,并且始终显示-即使服务未运行.

Data messages are delivered to system tray and are always display - even if service is not running.

通知消息如下:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    }
  }
}

并触发FirebaseMessagingService的方法OnMessageReceaved().许多设备(尤其是华为和小米)都竭尽全力杀死后台服务,以防止电池耗尽.因此,FirebaseMessagingService并不是处理通知的最佳方法.

and triggers method OnMessageReceaved() of FirebaseMessagingService. Many devices (especially Huawei and Xiaomi) try to do everything to kill background services to prevent battery drain. So the FirebaseMessagingService isn't the best way to handle notifications.

第二种类型是数据消息:

Second type is Data message:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "data":{
      "Nick" : "Mario",
      "body" : "great match!",
      "Room" : "PortugalVSDenmark"
    }
  }
}

此类型由系统托盘处理,因此您无需运行任何服务即可获取通知.它的方法要方便得多,但是据我所知,它不能通过控制台来实现.

This type is handled by the system tray, so you don't need any of service running to get the notification. Its much more convenient method, but as far i know, it can't be achieved with the console.

您可能需要服务器API才能发送数据消息.

阅读以了解更多详细信息.

Read this for more details.

这篇关于在Android应用中未收到Firebase云推送通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆