2017-02-12 183 views
1

我正在开发一个具有Firebase通知的应用,我通过Firebase教程指南来了解如何发送和接收通知,但我在其他设备上收到2个通知,而不是收到1个从发送设备接收的通知,虽然该设备不应该接受这是从它发送发送了两次Firebase推送通知

我看到关于上传通知其他问题两次通知,但它并没有为我

PS工作:通知从具有标题编辑文本和正文编辑文本的自定义对话框发送

这里是明显的:

<service 
     android:name=".MyFirebaseInstanceIDService" 
     android:exported="false"> 
     <intent-filter> 
      <action 
       android:name="com.google.firebase.INSTANCE_ID_EVENT"/> 
     </intent-filter> 
    </service> 

<service 
     android:name=".MyFirebaseMessagingService" 
     android:exported="false"> 
     <intent-filter> 
      <action 
       android:name="com.google.firebase.MESSAGING_EVENT" /> 
     </intent-filter> 
    </service> 

我在gradle这个编译这些:

compile 'com.google.firebase:firebase-core:10.0.0' 
compile 'com.google.firebase:firebase-messaging:10.0.0' 

这里的自定义对话框代码:

builder = new AlertDialog.Builder(this); 
     final View view = View.inflate(this, R.layout.layout_send_notification, null); 
     builder.setView(view) 
       .setCancelable(true) 
       .setPositiveButton(getString(R.string.send), new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialogInterface, int i) { 
         EditText editMessage = (EditText) view.findViewById(R.id.notification_message); 
         EditText editTitle = (EditText) view.findViewById(R.id.notification_title); 
         Calendar now = Calendar.getInstance(); 
         int day = now.get(Calendar.DAY_OF_MONTH); 
         int month = now.get(Calendar.MONTH) + 1; 
         int year = now.get(Calendar.YEAR); 
         String message = editMessage.getText().toString().replace(' ', '_'); 
         String title = editTitle.getText().toString().replace(' ', '_'); 

         boolean cancel = false; 
         View focusView = null; 

         if (TextUtils.isEmpty(message)) { 
          editMessage.setError(getString(R.string.error_field_required)); 
          focusView = editMessage; 
          cancel = true; 
         } 

         if (TextUtils.isEmpty(title)) { 
          editTitle.setError(getString(R.string.error_field_required)); 
          focusView = editTitle; 
          cancel = true; 
         } 

         if (cancel) 
          focusView.requestFocus(); 
         else { 
          RequestQueue queue = Volley.newRequestQueue(NotificationsActivity.this); 
          String url = "https://mysite.here/send_push.php?" + 
            "message=" + message + 
            "&title=" + title + 
            "&day=" + day + 
            "&month=" + month + 
            "&year=" + year; 
          StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { 
           @Override 
           public void onResponse(String response) { 
            Log.d("send push response", response); 
           } 
          }, new Response.ErrorListener() { 
           @Override 
           public void onErrorResponse(VolleyError error) { 
            error.printStackTrace(); 
           } 
          }); 
          queue.add(request); 
         } 
        } 
       }) 
       .setNegativeButton(getString(R.string.button_cancel), new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialogInterface, int i) { 
         dialogInterface.cancel(); 
        } 
       }); 
     sendNotificationDialog = builder.create(); 

这里是firebaseMessagingService:

@Override 
public void onMessageReceived(RemoteMessage remoteMessage) { 
    sendNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); 
} 

private void sendNotification(String messageTitle, String messageBody) { 
    Intent intent = new Intent(this, SplashActivity.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) 
      .setContentTitle(messageTitle) 
      .setContentText(messageBody) 
      .setSmallIcon(R.drawable.ic_stat_spe_bau) 
      .setAutoCancel(true) 
      .setSound(defaultSoundUri) 
      .setContentIntent(pendingIntent); 

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

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

这里是firebaseInstanceIDService:

@Override 
public void onTokenRefresh() { 
    String refreshedToken = FirebaseInstanceId.getInstance().getToken(); 
    Log.d("firebase ID", refreshedToken); 
    sendRegistrationToServer(refreshedToken); 
} 

private void sendRegistrationToServer(String token) { 
    RequestQueue queue = Volley.newRequestQueue(getApplicationContext()); 
    String url = "https://mysite.here/insertFCM_ID.php?fcmID=" + token; 
    StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { 
     @Override 
     public void onResponse(String response) { 
      Log.d("fcm response", response); 
     } 
    }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      error.printStackTrace(); 
     } 
    }); 
    queue.add(request); 
} 

send_push.php代码:

<?php 
header("Content-type: application/json, charset=UTF-8"); 
require('db.php'); 

$db = mysqli_connect($host, $username, $password) or die('Could not connect'); 
mysqli_select_db($db, $db_name) or die(''); 
$message = $_GET['message']; 
$title  = $_GET['title']; 
$day  = $_GET['day']; 
$month  = $_GET['month']; 
$year  = $_GET['year']; 

$server_key = "somekey"; 
$sql  = 'select fcm_token from fcm_info'; 
$result  = mysqli_query($db, $sql) or print("Error"); 
$key  = array(); 

while ($row = mysqli_fetch_assoc($result)) { 
    $key[] = $row; 
} 

$headers = array(
    'Authorization: key=' . $server_key, 
    'Content-Type: application/json' 
); 
$single = ""; 

foreach($key as $value) { 
    $single = $value['fcm_token']; 

    $fields = array(
     'to' => $single, 
     'notification' => array(
      'title' => str_replace("_", " ", $title), 
      'body' => str_replace("_", " ", $message), 
      'vibrate' => 1, 
      'sound' => 1 
     ) 
    ); 
    $payload = json_encode($fields); 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send'); 
    curl_setopt($ch, CURLOPT_POST, true); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
    curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); 
    $result = curl_exec($ch); 
} 

mysqli_query($db, "INSERT INTO notifications (title, body, day, month, year) VALUES ('$title', '$message', '$day', '$month', '$year')"); 

mysqli_close($db); 
echo $result; 
?> 

我尝试了很多办法,以便找到问题的所在,但我不能知道它是什么

如果需要更多信息,我将重新编辑以添加所需信息

+0

嗨。你可以发布你的'send_push.php'(删除敏感细节)吗?另外,从您的服务器发送消息后,您是否也收到双重响应? –

+0

你是说如果通知在我的数据库中注册了两次?如果是的话,那么是啊,这是 –

+0

嗨。不。我指的是从你的服务器发送消息,你收到FCM服务器的响应(可能是'200 OK'响应),你是否也收到过两次? –

回答

0

在您的onMessageReceived事件中创建注释行:

//sendNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); 
} 

在firebaseInstanceIDService类中进行此更改后再试一次。应该没问题。 如果您只想使用下游消息,则需要确定消息类型。数据信息或通知。您还需要在设备上管理您的应用的三种情况:前景,背景和已杀死。数据消息始终在您的服务上触发onMessageReceived事件。发送通知消息时这是不同的。我建议你发送数据消息作为发布请求。你现在没有任何问题。您正在通过Volley发送Post请求至'https://fcm.googleapis.com/fcm/send'URL,并且您正在发送通知。然后,您的服务正在接收您的通知并创建另一个通知。收到2个通知是非常正常的,因为您的代码正在生成2个通知。我告诉你做评论线并测试它。