显示应用程序在后台通过api获取的Firebase消息的通知 [英] Show Notification of Firebase Message onRecieved when App is in Background Through api

查看:898
本文介绍了显示应用程序在后台通过api获取的Firebase消息的通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经建立了一个聊天应用程序。它工作正常。这两个用户可以轻松地聊天
,但我得到卡住的是,如果一个用户的应用程序是在后台和屏幕关闭,用户无法收到通知收到的消息。



现在我想要的是在我的应用程序中,当用户A发送消息给用户B,用户B移动空闲但应用程序在后台运行时,用户B可以得到关于该消息的通知。用户B可以打开聊天活动并阅读消息。

我的firebase通知是从Firebase控制台运行的,但是我不知道如何调用实例ID并将其发送到特定的设备,并且特定的用户会收到有关收到的通知消息,当应用程序屏幕关闭和应用程序正在运行在后台状态。我应该如何实现它。任何帮助将不胜感激。谢谢

我在这里有我的firebase实例id服务类:

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

@Override
public void onTokenRefresh(){

//获取注册令牌
String refreshedToken = FirebaseInstanceId.getInstance()。getToken();

//在logcat上显示标记
Log.d(TAG,Refreshed token:+ refreshedToken);


$ b private void sendRegistrationToServer(String token){
//你可以实现这个方法来在你的服务器上存储令牌
// Not目前需要的项目




$ b code $


这是我的MyFirebase消息服务类

  public class MyFirebaseMessagingService extends FirebaseMessagingService { b $ b @Override 
public void onMessageReceived(RemoteMessage remoteMessage){
if(remoteMessage.getNotification()。getBody()!= null){
Log.e(FIREBASE,消息通知正文:+ 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());


$ b $ / code $ / pre
$ b

这里是我的聊天活动:

  public class Chat扩展AppCompatActivity {
LinearLayout布局;
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 $ b $ 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 (新的意图(Chat.this,ConnectActivity.class));


$ b}
});

reference1.addChildEventListener(new ChildEventListener(){
@Override $ b $ 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:-\\\
+ message,1);
}
else {
addMessageBox (UserDetails.chatWith +:-\\\
+ message,2);
}
}
$ b $ @覆盖
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(
是,
new DialogInterface.OnClickListener(){$ b $ public void onClick(DialogInterface对话框,int id){

finish();

dialog.cancel();
}
});

builder1.setNegativeButton(
不,
新的DialogInterface.OnClickListener(){
public void onClick(DialogInterface对话框,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);



$ div $解析方案

解决了这个问题可能有助于别人,

为了通过api发送firebase通知到单个设备如下:

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

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

@Override
public void onTokenRefresh(){

//获取注册令牌
String refreshedToken = FirebaseInstanceId.getInstance()。getToken();

//在logcat上显示标记
Log.d(TAG,Refreshed token:+ refreshedToken);

sendRegistrationToServer(refreshedToken);


$ b private void sendRegistrationToServer(String token){
//你可以实现这个方法来在你的服务器上存储令牌
// Not当前项目所需的



$ b}

}

注意:您可以从应用程序的任何位置调用实例标识,如下所示:

  String tkn = FirebaseInstanceId.getInstance()。getToken(); 
Toast.makeText(Doc_users.this,Current token [+ tkn +],
Toast.LENGTH_LONG).show();
Log.d(App,Token [+ tkn +]);

必须使用此令牌向单个设备发送通知,这是您可以存储的设备的ID它在您的firebase数据库中

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

2:现在您可以构建逻辑来获取这些ID并构建您的请求<我们可以通过这个方法来实现这个功能:

pre $ public $ {
JSONObject json = new JSONObject();
JSONObject info = new JSONObject();
info.put(title,Notification Title); //通知标题
info.put(body,Notification body); //通知正文
info.put(sound,mySound); //通知声音
json.put(notification,info);
json.put(to,INSTANCE ID FEEDED SIGNED 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 =您的FIREBASE SERVER KEY);
urlConnection.setRequestMethod(POST);
urlConnection.connect();

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

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

String line = null;
StringBuilder sb = new StringBuilder(); ((line = bufferedReader.readLine())!= null){
sb.append(line);

while
}

bufferedReader.close();
result = sb.toString();
$ b $ catch(UnsupportedEncodingException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
返回结果;

$ / code>

通知将在您的设备发送的单个设备上生成,您可以调试你自己的设备密钥,并使用邮递员的有效请求:好运


I have built a chat application . It is working fine . both users can chat easily but where i get Stuck is if one user's app is at background and screen is off , user is unable to be notified of that received message.

What i want now is in my application is when userA sends message to userB , and userB mobile is idle but application is running in background, userB can get notification about that message. and userB can open the chat activity and read the message .

My firebase notification is working from firebase console but i don't know how to call instance id and send that to particular device from api and particular user get notification about the recieved message , when application screen is off and application is running in background state . how should i achieve it . any help would be much appreciated . Thanks

I have my firebase instance id service class here:

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
    }



}

Here is my MyFirebase Messaging Service Class

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());
    }

}

Here is my chat Activity:

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);
    }
}

解决方案

I solved this problem may it help someone ,

In order to send Notification of firebase through api to single device is as follows:

1: generate Instance Id , unique for every device

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




}

}

Note: you can call Instance Id from any where in your Application Like this:

String tkn = FirebaseInstanceId.getInstance().getToken();
        Toast.makeText(Doc_users.this, "Current token ["+tkn+"]",
                Toast.LENGTH_LONG).show();
        Log.d("App", "Token ["+tkn+"]");

this token must be used to send notification to single device it is the id of the device you can store it in your firebase database

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

2:Now You can build your logic to fetch these ids and build your request

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;
    }

Notification will generate on that single device sent from your device you can debug to put your own device key and use postman for valid request: Good Luck

这篇关于显示应用程序在后台通过api获取的Firebase消息的通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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