Firebase FCM令牌未生成

时间:2018-10-05 04:57:06

标签: android firebase firebase-cloud-messaging

我想集成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>

我尝试过的事情

  1. 在控制台上删除项目,然后再次创建
  2. 将整个项目复制到新文件夹,然后在Android Studio中再次打开
  3. 尝试了以上两种服务
  4. 尝试调用FirebaseInstanceId.getToken(),但这会导致空指针异常。

6 个答案:

答案 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生命周期一章。

我可以看到两点可能出错的地方:

  1. 您与Google服务器没有连接。打开设备并打开网页,检查互联网连接是否正常。另外还要考虑代理和防火墙,它们可能会阻止您的通信(例如,如果您在中国,则长防火墙可能会阻止您与实例ID服务器的连接)。

  2. 确保您没有令牌。这是很常见的错误。您实现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类和一个接口

  1. 接口:

    public interface FCMTokenInterface {
        void onTokenReceived(String token);
        void onFailure();
    }
    
  2. 令牌侦听器类:

        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);
            }
    
        }
    
  3. 消息接收类:

    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;
    }
    }
    
  4. 启动时的实现界面:

    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)
        }
    }
    
  5. 在应用标签下的清单

    <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之前,首次添加应用程序时便生成了令牌。因此,现在获取令牌,您可以做两件事:

  1. 卸载并重新安装该应用程序。删除该应用程序将删除现有令牌,然后它将在重新安装时生成一个新令牌,并调用您的onTokenRefresh / onNewToken
  2. 还请求令牌,例如您的MainActivity.onCreate

    public class MainActivity extends AppCompatActivity {
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        ...
        String iidToken = FirebaseInstanceId.getInstance().getToken();
        Log.d("Firebase", "Got token: " + iidToken);