在应用程序处于后台时通过API显示Firebase消息的通知接收

6
我创建了一个聊天应用程序,它能够正常运行。两个用户都可以轻松聊天。但是,如果其中一个用户的应用程序在后台且屏幕关闭,则该用户将无法收到接收到的消息通知。
现在我想要实现的是,在我的应用程序中,当用户A向用户B发送消息时,如果用户B的手机处于空闲状态但应用程序在后台运行,则用户B可以收到有关该消息的通知。用户B可以打开聊天界面并阅读该消息。
我的Firebase通知从Firebase控制台工作正常,但是我不知道如何调用实例ID并从API发送到特定设备,以便特定用户通知收到的消息,当应用程序屏幕关闭且应用程序处于后台状态时。我该如何实现它?
这是我的Firebase实例ID服务类:
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
    private static final String TAG = "MyFirebaseIIDService";

    @Override
    public void onTokenRefresh() {

        //Getting registration token
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();

        //Displaying token on logcat
        Log.d(TAG, "Refreshed token: " + refreshedToken);
    }

    private void sendRegistrationToServer(String token) {
        //You can implement this method to store the token on your server
        //Not required for current project
    }
}

这是我的MyFirebase消息服务类

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if (remoteMessage.getNotification().getBody() != null) {
            Log.e("FIREBASE", "Message Notification Body: " + remoteMessage.getNotification().getBody());
            sendNotification(remoteMessage);
        }
    }

    private void sendNotification(RemoteMessage remoteMessage) {
        RemoteMessage.Notification notification = remoteMessage.getNotification();
        Intent intent = new Intent(this, LoggedInView.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.first_aid))
                .setSmallIcon(R.drawable.first_aid)
                .setContentTitle(notification.getTitle())
                .setContentText(notification.getBody())
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

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

这是我的聊天活动:

public class Chat extends AppCompatActivity {
    LinearLayout layout;
    ImageView sendButton,vidcall;
    EditText messageArea;
    ScrollView scrollView;
    Firebase reference1, reference2;

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

        layout = (LinearLayout)findViewById(R.id.layout1);
        sendButton = (ImageView)findViewById(R.id.sendButton);
        vidcall = (ImageView)findViewById(R.id.vidBtnk);
        messageArea = (EditText)findViewById(R.id.messageArea);
        scrollView = (ScrollView)findViewById(R.id.scrollView);

        Firebase.setAndroidContext(this);
        reference1 = new Firebase("https://*******.firebaseio.com/messages/" + UserDetails.username + "_" + UserDetails.chatWith);
        reference2 = new Firebase("https://*******.firebaseio.com/messages/" + UserDetails.chatWith + "_" + UserDetails.username);

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String messageText = messageArea.getText().toString();

                if(!messageText.equals("")){
                    Map<String, String> map = new HashMap<String, String>();
                    map.put("message", messageText);
                    map.put("user", UserDetails.username);
                    reference1.push().setValue(map);
                    reference2.push().setValue(map);
                }
                messageArea.setText("");
            }
        });

        vidcall.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                startActivity(new Intent(Chat.this, ConnectActivity.class));



            }
        });

        reference1.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                Map map = dataSnapshot.getValue(Map.class);
                String message = map.get("message").toString();
                String userName = map.get("user").toString();

                if(userName.equals(UserDetails.username)){
                    addMessageBox("You:-\n" + message, 1);
                }
                else{
                    addMessageBox(UserDetails.chatWith + ":-\n" + message, 2);
                }
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });
    }


   // boolean doubleBackToExitPressedOnce = false;

    @Override
    public void onBackPressed() {

        AlertDialog.Builder builder1 = new AlertDialog.Builder(Chat.this);
        builder1.setMessage("CAUTION! -> Do Wish to End this Session");
        builder1.setCancelable(true);
        builder1.setPositiveButton(
                "Yes",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {

                        finish();

                        dialog.cancel();
                    }
                });

        builder1.setNegativeButton(
                "No",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });

        AlertDialog alert11 = builder1.create();
        alert11.show();


    }


    public void addMessageBox(String message, int type){
        TextView textView = new TextView(Chat.this);
        textView.setText(message);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lp.setMargins(0, 0, 0, 10);
        textView.setLayoutParams(lp);

        if(type == 1) {
            textView.setBackgroundResource(R.drawable.rounded_corner1);
        }
        else{
            textView.setBackgroundResource(R.drawable.rounded_corner2);
        }

        layout.addView(textView);
        scrollView.fullScroll(View.FOCUS_DOWN);
    }
}
4个回答

19
您需要一个在后台运行的服务来接收PUSH通知并将其显示给用户,这正是Firebase通知服务所提供的。我有一个这样的服务(您需要根据自己的需求进行修改以实现通知显示时要做的操作):

您需要一个在后台运行的服务来接收PUSH通知并将其显示给用户,这正是Firebase通知服务所提供的。我有一个这样的服务(您需要根据自己的需求进行修改以实现通知显示时要做的操作):

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if (remoteMessage.getNotification().getBody() != null) {
            Log.e("FIREBASE", "Message Notification Body: " + remoteMessage.getNotification().getBody());
            sendNotification(remoteMessage);
        }
    }

    private void sendNotification(RemoteMessage remoteMessage) {
        RemoteMessage.Notification notification = remoteMessage.getNotification();
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.logo_gris))
                .setSmallIcon(R.drawable.logo_gris)
                .setContentTitle(notification.getTitle())
                .setContentText(notification.getBody())
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

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


}

我不知道如何将 Firebase 通知服务集成到我目前正在运行的聊天应用程序中,你能提供任何完整的示例或教程吗? - Addi.Star
好的,我尝试了你的解决方案,并能够从Firebase控制台接收通知,但我想将其集成到我的聊天类中。 - Addi.Star
你想让它做什么? - Nahue
请查看我的chat.java类。在这个类中,我发送/接收文本消息。现在当一个用户的手机屏幕关闭或应用程序在后台运行时,用户应该收到有关传入消息的通知,以便可以点击打开它来阅读消息。 - Addi.Star
NotificationCompat.Builder(this) 已经被弃用,您可以使用 NotificationCompat.Builder(this, channelId) 代替。例如请参考 https://github.com/firebase/quickstart-android/blob/14b5e47b8af5e7019bdba94c2e6969a2c58c0165/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/java/MyFirebaseMessagingService.java#L58-L101 - yaircarreno
显示剩余2条评论

0

你好,我已经使用Firebase Messaging实现了聊天应用程序。

以下是你可以实现的步骤:

1)实现sendRegistrationToServer(String token){ 进行异步调用以存储在后端服务器中生成的令牌(将用户与生成的令牌映射) }

2)在聊天活动中,sendmessage()应向服务器发送消息到secondUser()

3)通过查看usertoken,我们应该从后端服务器向Firebase服务器推送通知。

4)实现onMessageReceived()以显示通知


0

0

我解决了这个问题,希望能帮到某些人,

通过API向单个设备发送Firebase通知的步骤如下:

1:生成实例ID,对于每个设备都是唯一的

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";

@Override
public void onTokenRefresh() {

    //Getting registration token
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();

    //Displaying token on logcat
    Log.d(TAG, "Refreshed token: " + refreshedToken);

    sendRegistrationToServer(refreshedToken);

}

private void sendRegistrationToServer(String token) {
    //You can implement this method to store the token on your server
    //Not required for current project




}

}

注意:您可以从应用程序的任何位置调用实例 ID,如下所示:
String tkn = FirebaseInstanceId.getInstance().getToken();
        Toast.makeText(Doc_users.this, "Current token ["+tkn+"]",
                Toast.LENGTH_LONG).show();
        Log.d("App", "Token ["+tkn+"]");

此令牌必须用于向单个设备发送通知,它是设备的标识符,您可以将其存储在Firebase数据库中。

 reference.child(UserDetails.username).child("token").setValue(tokun);

2:现在,您可以构建逻辑来获取这些 ID 并构建请求

public static String makeRequest(String id) throws JSONException {
        HttpURLConnection urlConnection;
        JSONObject json = new JSONObject();
        JSONObject info = new JSONObject();
        info.put("title", "Notification Title");   // Notification title
        info.put("body", "Notification body"); // Notification body
        info.put("sound", "mySound"); // Notification sound
        json.put("notification", info);
        json.put("to","INSTANCE ID FETCHED FOR SIGNLE DEVICE HERE");
        Log.e("deviceidkey==> ",id+"");
        Log.e("jsonn==> ",json.toString());
        String data = json.toString();
        String result = null;
        try {
            //Connect
            urlConnection = (HttpURLConnection) ((new URL("https://fcm.googleapis.com/fcm/send").openConnection()));
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Content-Type", "application/json");
            urlConnection.setRequestProperty("Authorization", "key=YOUR FIREBASE SERVER KEY");
            urlConnection.setRequestMethod("POST");
            urlConnection.connect();

            //Write
            OutputStream outputStream = urlConnection.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
            writer.write(data);
            writer.close();
            outputStream.close();

            //Read
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));

            String line = null;
            StringBuilder sb = new StringBuilder();

            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
            }

            bufferedReader.close();
            result = sb.toString();

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

通知将在单个设备上生成,从您的设备发送,您可以调试以放置自己的设备密钥并使用Postman进行有效请求:祝你好运


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接