我正在创建具有推送通知功能的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');
}
?>
也许任何人都可以记录我的代码,所以我会非常感谢..
答案 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>
我希望我帮助过(: