Android推送通知Firebase有时不会发送通知

时间:2016-12-22 02:19:06

标签: android firebase firebase-cloud-messaging

我正在创建具有推送通知功能的Android应用。我的问题是;有时我的应用程序收到通知但有时不收到。我一直在Google上搜索此问题,没有人遇到同样的问题。我需要帮助。以下是我的代码。

这是一个gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"
    defaultConfig {
        applicationId "com.example.rusla.manual_notif"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.0.1'
    compile 'com.google.firebase:firebase-messaging:10.0.0'
    testCompile 'junit:junit:4.12'
    compile 'com.mcxiaoke.volley:library:1.0.19'
}


apply plugin: 'com.google.gms.google-services'

这是清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rusla.manual_notif">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".RegisterActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".MyFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>


        <service android:name=".FirebaseIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>
    </application>

</manifest>

这是我的注册令牌类

package com.example.rusla.manual_notif;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.firebase.iid.FirebaseInstanceId;

import java.util.HashMap;
import java.util.Map;

public class RegisterActivity extends AppCompatActivity {
    private EditText editTextEmail;
    String REGISTER_URL = "http://192.168.0.7/fcm_server/register.php";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.register_layout);
        Button regBtn = (Button) findViewById(R.id.buttonRegister);
        editTextEmail = (EditText) findViewById(R.id.editTextEmail);
        regBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                // Get token
                String token = FirebaseInstanceId.getInstance().getToken();
                //Finally we need to implement a method to store this unique id to our server
                sendIdToServer(token);
            }
        });
    }

    private void sendIdToServer(final String token) {
        //Creating a progress dialog to show while it is storing the data on server
        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Registering device...");
        progressDialog.show();

        //getting the email entered
        final String email = editTextEmail.getText().toString().trim();

        //Creating a string request
        StringRequest req = new StringRequest(Request.Method.POST, REGISTER_URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        //dismissing the progress dialog
                        progressDialog.dismiss();
                        //if the server returned the string success
                        if (response.trim().equalsIgnoreCase("success")) {
                            //Displaying a success toast
                            Toast.makeText(RegisterActivity.this, "Registered successfully", Toast.LENGTH_SHORT).show();

                        } else {
                            Toast.makeText(RegisterActivity.this, "Choose a different email", Toast.LENGTH_SHORT).show();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                //adding parameters to post request as we need to send firebase id and email
                params.put("token", token);
                params.put("email", email);
                return params;
            }
        };

        //Adding the request to the queue
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(req);
    }

}

这是我的Firebase服务类

package com.example.rusla.manual_notif;

import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

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

    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);

        // TODO: Implement this method to send any registration to your app's servers.
        sendRegistrationToServer(refreshedToken);
    }

    private void sendRegistrationToServer(String token) {
        // Add custom implementation, as needed.
    }
}

,这是

package com.example.rusla.manual_notif;

import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "FCM Service";
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // TODO: Handle FCM messages here.
        // If the application is in the foreground handle both data and notification messages here.
        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated.
        Log.d(TAG, "From: " + remoteMessage.getFrom());
        Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
    }
}

以下是我用来发送通知的服务器端php代码

<!DOCTYPE html>
<html>
<head>
    <title>Firebase Push Notification</title>
</head>
<style type="text/css">
    html, body {
        height: 100%;
    }

    html {
        display: table;
        margin: auto;
    }

    body {
        display: table-cell;
        vertical-align: middle;
    }
    textarea {
        width: 300px;
        height: 150px;
    }
</style>

<body>
    <?php
    require_once 'database.php';
    $sql = "SELECT * FROM users";
    $result = mysqli_query($conn,$sql);

    ?>
    <?php
    //Displaying a success message when the notification is sent 
    if(isset($_REQUEST['success'])){
        ?>
        <strong>Great!</strong> Your message has been sent successfully...
        <?php
    }
    ?>

    <form action='send.php' method='post'>
        <select name='token'>
            <?php 
            //Traversing trhough all values 
            while($row = mysqli_fetch_array($result)){
            //displaying the values in a dropdown list 
                ?>
                <option value='<?php echo $row['token'];?>'><?php echo $row['email'];?></option>

                <?php
            }
            ?>
        </select><br /><br />
        <textarea name='message'></textarea><br />

        <button>Send Notification</button><br />
    </form>

</body>
</html>

,而且

<?php 

function send_notification ($tokens, $message)
{
    $url = 'https://fcm.googleapis.com/fcm/send';

    $msg = array
    (
        'body'  => "$message",
        'title'     => "SATPOL PP SDA - SIAP",
        'sound'     => 'default'

        );
    $fields = array
    (
        'registration_ids'  => $tokens,
        'notification'          => $msg
        );


    $headers = array(
        'Authorization:key = AIzaSyAdnDaeFRbG7jD74-yo0R72n7b24Wzsh7k',
        'Content-Type: application/json'
        );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);  
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
    $result = curl_exec($ch);           
    if ($result === FALSE) {
        die('Curl failed: ' . curl_error($ch));
    }
    curl_close($ch);
    return $result;
}

//Checking post request 
if($_SERVER['REQUEST_METHOD']=='POST'){
    //Geting email and message from the request 
    $tokens[] = $_POST['token'];
    $message = $_POST['message'];
    $message_status = send_notification($tokens, $message);
    $result = json_decode($message_status);

    if($result->success){
        header('Location: sendNotification.php?success');
    }else{
        echo "<pre>";print_r($result);die; 
    }
}else{
    header('Location: sendNotification.php');
}


?>

也许任何人都可以记录我的代码,所以我会非常感谢..

2 个答案:

答案 0 :(得分:3)

如果您不更新Firebase注册令牌(它会动态更新),则可能是您的服务器端令牌已过期,并且您没有使用设备的新注册令牌更新服务器。因此,永远不会收到该消息。 根据我的研究,可能是您的有效负载有时超过了“ 4KB”大小限制,或者是我想怀疑Firebase的错误。

答案 1 :(得分:0)

我建议您使用data代替notification。数据消息始终加载onMessageReceived。

阅读如何使用数据,编辑脚本(php)以使用数据而不是通知。

然后,按照以下方式发出自己的通知:

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        // Use data! (:
        if(remoteMessage.getData().size() > 0) {

            if (remoteMessage.getData().get("message") != null) {

                String title = (remoteMessage.getData().get("title") != null) ? remoteMessage.getData().get("title") : "Default Notification Title";
                showNotification(title, remoteMessage.getData().get("message"));

            }

        }

        // When you send notification from the firebase console (avoid it for now. Is still very new)
        if (remoteMessage.getNotification() != null) {

            String title = (remoteMessage.getNotification().getTitle() != null) ? remoteMessage.getNotification().getTitle() : "Default Notification Title";

            showNotification(title, remoteMessage.getNotification().getBody());


        }
    }

private void showNotification(String title, String message){

Intent iNotifi;
iNotifi = new Intent(this, MainActivity.class);
            iNotifi.setAction(Intent.ACTION_MAIN);
            iNotifi.addCategory(Intent.CATEGORY_LAUNCHER);

PendingIntent pi = PendingIntent.getActivity(this, 0, iNotifi, 0);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

        builder.setSmallIcon(R.drawable.yourNotificationIcon);
        builder.setTicker(title);
        builder.setContentTitle(title);
        builder.setContentText(message);
builder.setContentIntent(pi);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            int color = ContextCompat.getColor(this, R.color.yourAccentColor);
            builder.setColor(color);
        }

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

        try {
            nm.notify(0, builder.build());
        } catch (Exception e) {
            e.printStackTrace();
        }

}

在你的Manifest中添加:

<application...>


<!-- Firebase notification icon -->
        <meta-data android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/yourNotificationIcon" />
        <meta-data android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/yourAccentColor" />

</application>

我希望我帮助过(:

相关问题