首页 > 解决方案 > Firebase 聊天应用接收通知

问题描述

我正在构建一个不需要服务器设置的 android firebase 聊天应用程序,我已经为它构建了所有内容,并找到了一些关于如何解决我现在遇到问题的 YouTube 教程,我正在尝试让应用程序本身向发送消息的设备发送推送通知,我正在使用 Volley 发送通知,我面临的问题是其他设备没有收到或显示通知,你能请告诉我我做错了什么以及如何解决?

构建.gradle

implementation 'com.google.firebase:firebase-auth:20.0.4'
implementation 'com.google.firebase:firebase-database:19.7.0'
implementation platform('com.google.firebase:firebase-bom:27.0.0')
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-messaging:20.0.1'
implementation 'com.android.volley:volley:1.1.1'

AndroidManifest

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

...

<service
   android:name=".MyFirebaseMessagingService"
   android:permission="com.google.android.c2dm.permission.SEND">
   <intent-filter>
       <action android:name="com.google.firebase.MESSAGING_EVENT" />
       <action android:name="com.google.android.c2dm.intent.RECEIVE" />
   </intent-filter>
</service>
<service
   android:name=".MyFirebaseInstanceIDService">
   <intent-filter>
       <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
   </intent-filter>
</service>

MyFirebaseInstanceIDService

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {

    private static final String TAG = "mFirebaseIIDService";

    @Override
    public void onTokenRefresh() {
        FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
        final String token = FirebaseInstanceId.getInstance().getToken();
        FirebaseInstallations.getInstance().getToken(false)
                .addOnCompleteListener(new OnCompleteListener<InstallationTokenResult>() {
                    @Override
                    public void onComplete(@NonNull Task<InstallationTokenResult> task) {
                        FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
                        FirebaseMessaging.getInstance().subscribeToTopic(user.getUid());
                        Log.i("TAG", "onTokenRefresh completed with token: " + task.getResult().getToken());
                    }
                });
    }
}

MyFirebase 消息服务

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private final String ADMIN_CHANNEL_ID = "admin_channel";

    @Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
        final Intent intent = new Intent(this, MainActivity.class);
        NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        int notificationID = new Random().nextInt(85-65);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            setupChannels(notificationManager);
        }

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this , 0, intent,
                PendingIntent.FLAG_ONE_SHOT);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, ADMIN_CHANNEL_ID)
                .setContentTitle(remoteMessage.getData().get("title"))
                .setContentText(remoteMessage.getData().get("message"))
                .setAutoCancel(true)
                .setSound(notificationSoundUri)
                .setContentIntent(pendingIntent);

        notificationManager.notify(notificationID, notificationBuilder.build());
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void setupChannels(NotificationManager notificationManager){
        CharSequence adminChannelName = "New notification";
        String adminChannelDescription = "Device to device notification";

        NotificationChannel adminChannel;
        adminChannel = new NotificationChannel(ADMIN_CHANNEL_ID, adminChannelName, NotificationManager.IMPORTANCE_HIGH);
        adminChannel.setDescription(adminChannelDescription);
        adminChannel.enableLights(true);
        adminChannel.setLightColor(Color.RED);
        adminChannel.enableVibration(true);
        if (notificationManager != null) {
            notificationManager.createNotificationChannel(adminChannel);
        }
    }
}

消息活动

final private String FCM_API = "https://fcm.googleapis.com/fcm/send";
final private String serverKey = "key=MY_KEY";
final private String contentType = "application/json";
final String TAG = "NOTIFICATION TAG";

...

sendBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        String msg = msg_editText.getText().toString();
        if (!msg.equals("")) {
            sendMessage(fuser.getUid(), userid, msg);
            JSONObject notification = getStructure(fuser.getUid(), userid, msg);
            sendNotification(notification);
        }

        msg_editText.setText("");
    }
});

...

private JSONObject getStructure(String senderId, String receiverId, String msg) {
    JSONObject notification = new JSONObject();
    JSONObject notificationBody = new JSONObject();
    try {
        notificationBody.put("title", "App Test");
        notificationBody.put("message", "This is a test notification from the app");

        notification.put("to", "/topics/" + receiverId);
        notification.put("data", notificationBody);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return notification;
}

...

private void sendNotification(JSONObject notification) {

    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(FCM_API, notification,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.i(TAG, "onResponse: " + response.toString());
                }
        }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(MessageActivity.this, "Request error", Toast.LENGTH_SHORT).show();
            Log.i(TAG, "onErrorResponse: Didn't work");
        }
    }) {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> params = new HashMap<>();
            params.put("Authorization", serverKey);
            params.put("Content-Type", contentType);
            return params;
        }
    };

    MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonObjectRequest);

}

我的单身人士

public class MySingleton {

    private static MySingleton instance;
    private RequestQueue requestQueue;
    private Context ctx;

    public MySingleton(Context ctx) {
        this.ctx = ctx;
        requestQueue = getRequestQueue();
    }

    public static synchronized MySingleton getInstance(Context context) {
        if (instance == null) {
            instance = new MySingleton(context);
        }
        return instance;
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
        }
        return requestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }
}

标签: javaandroidfirebasefirebase-realtime-database

解决方案


推荐阅读