我想集成fcm以在我的应用程序中具有推送通知功能。但是问题是我的fcm令牌根本没有生成。我在本项目中使用了与我在本项目中使用的相同的代码,该代码工作正常。
但是在这个项目中,我尝试了所有尝试,但都没有结果。
我尝试使用不推荐使用的onTokenRefresh()
方法和新的onNewToken()
方法,但是没有一个对我有用。
下面是相同的代码。
public class CustomFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
// TODO(developer): Handle FCM messages here.
Log.d("Firebase", "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d("Firebase", "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d("Firebase", "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
@Override
public void onNewToken(String s) {
super.onNewToken(s);
Log.d("token",s);
}
}
这是带有onTokenRefresh()方法的代码
public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService {
@Override
public void onTokenRefresh() {
super.onTokenRefresh();
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d("Firebase", "Refreshed token: " + refreshedToken);
}
}
我也在清单中声明了这两种服务。
<service android:name=".notification.CustomFirebaseMessagingService"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service
android:name=".notification.MyFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
我尝试过的事情
FirebaseInstanceId.getToken()
,但这会导致空指针异常。答案 0 :(得分:0)
正如@Nilesh Rathod所说,FirebaseInstanceIdService已弃用。因此,您不需要清单中的一项服务。
尝试这种方式。 1.首先创建服务
public class YourService extends FirebaseMessagingService {
public static int NOTIFICATION_ID = 1;
@Override
public void onNewToken(String s) {
super.onNewToken(s);
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
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 mNotifyBuilder = new NotificationCompat.Builder(this, "2")
.setSmallIcon(R.drawable.your_icon)
.setContentTitle(remoteMessage.getNotification().getTitle())
.setContentText(remoteMessage.getNotification().getBody())
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (NOTIFICATION_ID > 1073741824) {
NOTIFICATION_ID = 0;
}
Objects.requireNonNull(notificationManager).notify(NOTIFICATION_ID++, mNotifyBuilder.build());
}
}
现在将其添加到清单
<service
android:name=".YourService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
答案 1 :(得分:0)
除了实现错误外,还要查看实例ID的工作原理:https://developers.google.com/instance-id/,请查看底部的实例ID生命周期一章。
我可以看到两点可能出错的地方:
您与Google服务器没有连接。打开设备并打开网页,检查互联网连接是否正常。另外还要考虑代理和防火墙,它们可能会阻止您的通信(例如,如果您在中国,则长防火墙可能会阻止您与实例ID服务器的连接)。
确保您没有令牌。这是很常见的错误。您实现ID令牌服务,然后运行该应用程序。现在您想将令牌发送到服务器,并为其编写代码,它可以正常工作。再次运行该应用程序时,您将看不到与服务器的连接,并认为您的实现存在问题。
实际发生的情况是,您在第一次运行时就已经拥有令牌,并且令牌已由应用程序缓存。第二次它已经具有令牌,并且onNewToken()
将不会被调用。
如果您卸载该应用程序,然后重新安装,它将在启动时要求新的令牌。
答案 2 :(得分:0)
firebase令牌的生成是在应用程序的首次安装中,或者当您删除应用程序的缓存时,此示例代码对我有用 公共类MyFirebaseInstanceIdService扩展了FirebaseInstanceIdService {
SharedPreferences sharedPreferences1;
SharedPreferences.Editor editor1;
private static final String PREF_NAME1 = "prefs_token";
private static final String KEY_FCM = "devices_token";
//this method will be called
//when the token is generated
@Override
public void onTokenRefresh() {
sharedPreferences1 = getSharedPreferences(PREF_NAME1, Context.MODE_PRIVATE);
editor1 = sharedPreferences1.edit();
super.onTokenRefresh();
//now we will have the token
String token = FirebaseInstanceId.getInstance().getToken();
editor1.putString(KEY_FCM,token.toString());
editor1.apply();
//for now we are displaying the token in the log
//copy it as this method is called only when the new token is generated
//and usually new token is only generated when the app is reinstalled or the data is cleared
Log.d("MyRefreshedToken", token);
String device_token = sharedPreferences1.getString(KEY_FCM, "");
}
}
答案 3 :(得分:0)
在APP中创建两个Java类和一个接口
接口:
public interface FCMTokenInterface {
void onTokenReceived(String token);
void onFailure();
}
令牌侦听器类:
public class MyInstanceIDListenerService extends FirebaseInstanceIdService {
private static FCMTokenInterface fcmTokenCallback;
private static Handler handlerOs = new Handler();
private static int delay=20000;
private static final String TAG = "MyFirebaseIIDService";
private static final String FRIENDLY_ENGAGE_TOPIC = "friendly_engage";
@Override
public void onTokenRefresh() {
String token = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "FCM Token: 3" + token);
//putting token in preference
Prefs.putString(Constant.FCM_TOKEN,token);
FirebaseMessaging.getInstance()
.subscribeToTopic(FRIENDLY_ENGAGE_TOPIC);
}
public static void setCallback(FCMTokenInterface callback) {
try {
String token = FirebaseInstanceId.getInstance().getToken();
if (token != null && !token.isEmpty()) {
//优先放置令牌 Prefs.putString(Constant.FCM_TOKEN,令牌); callback.onTokenReceived(token); 返回; } } catch(Exception e){ 重试(回调); Log.v(“ SetCallback EXP =”,e.toString()); } fcmTokenCallback =回调; // startHandler(); }
public static void retry(FCMTokenInterface callback)
{
setCallback(callback);
}
private static void startHandler() {
handlerOs.postDelayed(new Runnable() {
@Override
public void run() {
retry(fcmTokenCallback);
// fcmTokenCallback.onFailure();
fcmTokenCallback = null;
}
}, delay);
}
private static void clearHandler() {
handlerOs.removeCallbacksAndMessages(null);
}
}
消息接收类:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFMService";
String CHANNEL_ID = "com.app.app";
NotificationChannel mChannel;
private NotificationManager mManager;
private String title, msg, actionCode;
private int badge = 0;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Handle data payload of FCM messages.
Log.d(TAG, "FCM Message Id: " + remoteMessage.getMessageId());
Log.d(TAG, "FCM Notification Message: " + remoteMessage.getData() + "...." +
remoteMessage.getFrom());
if (remoteMessage.getData() != null) {
Map<String, String> params = remoteMessage.getData();
JSONObject object = new JSONObject(params);
//Log.e("JSON_OBJECT", object.toString());
title = object.optString("title","");
actionCode = object.optString("action_code", "");
msg = object.optString("body", "");
if (remoteMessage.getData().containsKey("badge")) {
badge = Integer.parseInt(remoteMessage.getData().get("badge"));
//Log.d("notificationNUmber", ":" + badge);
setBadge(getApplicationContext(), badge);
Prefs.putBoolean(Constant.HAS_BADGE,true);
}
if (!(title.equals("") && msg.equals("") && actionCode.equals(""))) {
createNotification(actionCode, msg, title);
}
else {
//Log.e("Notification", "Invalid Data");
}
}
}
public void createNotification(String action_code, String msg, String title) {
Intent intent = null;
intent = new Intent(this, HomeActivity.class);
intent.putExtra(Constant.ACTION_CODE, action_code);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel androidChannel = new NotificationChannel(CHANNEL_ID,
title, NotificationManager.IMPORTANCE_DEFAULT);
// Sets whether notifications posted to this channel should display notification lights
androidChannel.enableLights(true);
// Sets whether notification posted to this channel should vibrate.
androidChannel.enableVibration(true);
// Sets the notification light color for notifications posted to this channel
androidChannel.setLightColor(Color.GREEN);
// Sets whether notifications posted to this channel appear on the lockscreen or not
androidChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
getManager().createNotificationChannel(androidChannel);
Notification.Builder nb = new Notification.Builder(getApplicationContext(), CHANNEL_ID)
.setContentTitle(title)
.setContentText(msg)
.setTicker(title)
.setShowWhen(true)
.setSmallIcon(R.mipmap.ic_small_notification)
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_launcher_round))
.setAutoCancel(true)
.setContentIntent(contentIntent);
getManager().notify(101, nb.build());
} else {
try {
@SuppressLint({"NewApi", "LocalSuppress"}) android.support.v4.app.NotificationCompat.Builder notificationBuilder = new android.support.v4.app.NotificationCompat.Builder(this).setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setSmallIcon(R.mipmap.ic_small_notification)
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_launcher_round))
.setContentTitle(title)
.setTicker(title)
.setContentText(msg)
.setShowWhen(true)
.setContentIntent(contentIntent)
.setLights(0xFF760193, 300, 1000)
.setAutoCancel(true).setVibrate(new long[]{200, 400});
/*.setSound(Uri.parse("android.resource://"
+ getApplicationContext().getPackageName() + "/" + R.raw.tone));*/
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify((int) System.currentTimeMillis() /* ID of notification */, notificationBuilder.build());
} catch (SecurityException se) {
se.printStackTrace();
}
}
}
private NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
}
启动时的实现界面:
class SplashActivity : AppCompatActivity(), FCMTokenInterface {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
MyInstanceIDListenerService.setCallback(this)
}
override fun onFailure() {
Log.d("Token", "Unable to get token.")
}
override fun onTokenReceived(token: String?) {
Log.d("Token", token)
Prefs.putString(Constant.FCM_TOKEN, token)
}
}
在应用标签下的清单
<service android:name="fcm.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name="fcm.MyInstanceIDListenerService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@mipmap/ic_launcher_round" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
答案 4 :(得分:0)
终于解决了我的问题。当我尝试集成OneSignal通知sdk时得到了这个提示。问题是清单的应用程序标记中包含以下代码。
tools:node="replace"
这是用OneSignal文档编写的。
确保您未使用tools:node =“ replace”
替换AndroidManifest.xml中的标签。
由于OneSignal也在内部使用FireBase,因此我想直接尝试使用Firebase,并且在删除它后可以正常工作。
希望这对其他人也有帮助
答案 5 :(得分:0)
仅当生成令牌时,才将onTokenRefresh
/ onNewToken
方法称为。在大多数情况下,令牌只是存在而不会被修改。在这段时间内,不会调用onTokenRefresh
/ onNewToken
。
很可能是,在您拥有onTokenRefresh
/ onNewToken
之前,首次添加应用程序时便生成了令牌。因此,现在获取令牌,您可以做两件事:
onTokenRefresh
/ onNewToken
。还请求令牌,例如您的MainActivity.onCreate
。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
...
String iidToken = FirebaseInstanceId.getInstance().getToken();
Log.d("Firebase", "Got token: " + iidToken);