0

我已經構建了一個聊天應用程序。它工作正常。兩個用戶都可以輕鬆地聊天 但是我得到Stuck的地方是如果一個用戶的應用程序在後臺並且屏幕關閉,用戶無法收到收到的消息的通知。顯示應用程序通過api後臺時接收到的Firebase消息的通知

我現在想要的是在我的應用程序中,當userA向userB發送消息,並且userB mobile空閒但應用程序在後臺運行時,userB可以獲得有關該消息的通知。用戶B可以打開聊天活動並閱讀消息。

我的Firebase通知正在Firebase控制檯中工作,但我不知道如何調用實例ID並將其發送到特定設備,並且特定用戶在應用程序屏幕關閉且應用程序正在運行時收到有關收到消息的通知在後臺狀態。我應該如何實現它?

我有我的火力實例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); 
    } 
} 

回答

0

我解決了這個問題,它可以幫助別人,

在爲了通過API來發送火力的通知到單個設備如下:

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+"]"); 

此令牌必須用於通知發送到單一設備就可以將其存儲在您的火力數據庫中的設備的ID

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

通知將在您的設備發送的單個設備上生成,您可以通過調試將自己的設備密鑰和郵遞員用於有效請求:好運

7

您需要在後臺運行的服務來捕獲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()); 
    } 


} 
+0

我不知道如何火力通知服務融入我當前正在運行的聊天應用程序,你可以提供任何完整的例子或教程。 –

+0

好吧我試過yor解決方案,並且能夠從firebase控制檯接收通知,但是我想將它集成到我的聊天類中 –

+0

你想要它做什麼? – Nahue

0

嗨我已經使用Firebase消息傳遞實現了聊天應用程序。

下面的步驟可以實現

1)實施sendRegistrationToServer(字符串令牌){ 使異步調用中產生的後端服務器(與令牌地圖用戶存儲令牌生成) }

2)在聊天活動sendmessage()應該消息到服務器secondUser()

3)通過查看usertoken我們應該推送通知從後端服務器到Firebase服務器。

4)實施onMessageReceived()來顯示通知

相關問題