48

在我的日誌MainActivity中,我可以看到使用FirebaseInstanceId.getInstance().getToken()的令牌,它顯示生成的令牌。但是看起來好像在我的MyFirebaseInstanceIDService中它擴展到FirebaseInstanceIdService那樣,onTokenRefresh()沒有被調用,在這個函數中它被稱爲令牌最初是在這裏生成的。我需要撥打sendRegistrationToServer()這就是爲什麼我想知道爲什麼它不在onTokenRefresh()Firebase onTokenRefresh()不叫

這裏是我的代碼

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService { 


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

     sendRegistrationToServer(refreshedToken); 
    } 
} 
+0

[Firebase FCM force onTokenRefresh()被稱爲]的可能重複(http://stackoverflow.com/questions/37454501/firebase-fcm-force-ontokenrefresh-to-be-called) – Machado

+0

請完整閱讀問題。這個問題不是你提到的問題的重複。 @Machado –

回答

75

僅在生成新標記時調用FirebaseInstanceIdService中的onTokenRefresh。如果您的應用程序先前已安裝並生成了令牌,則onTokenRefresh將不會被調用。嘗試卸載並重新安裝應用程序以強制生成新的令牌,這會導致onTokenRefresh被調用。

另外要確保你的FirebaseInstanceIdService在AndroidManifest.xml中

正確定義清單檔案中的。

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

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

FirebaseInstanceIdService類

public class MyFireBaseInstanceIDService extends FirebaseInstanceIdService { 


private static final String TAG = MyFireBaseInstanceIDService.class.getSimpleName(); 

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

    if (refreshedToken!=null) { 
     SettingPreferences.setStringValueInPref(this, SettingPreferences.REG_ID, refreshedToken); 
    } 
    // TODO: Implement this method to send any registration to your app's servers. 
    sendRegistrationToServer(refreshedToken); 
} 
// [END refresh_token] 

/** 
* Persist token to third-party servers. 
* 
* Modify this method to associate the user's FCM InstanceID token with any server-side account 
* maintained by your application. 
* 
* @param token The new token. 
*/ 
private void sendRegistrationToServer(String token) { 
    // Add custom implementation, as needed. 
}} 

FirebaseMessagingService類。

public class GCMNotificationIntentService extends FirebaseMessagingService { 
// Sets an ID for the notification, so it can be updated 


public GCMNotificationIntentService() { 
    super(); 
} 


@Override 
public void onMessageReceived(RemoteMessage message) { 

}} 
+0

該文檔似乎令人困惑(https://firebase.google.com/docs/cloud-messaging/android/client),它表示註冊令牌可能在以下情況下發生更改:應用程序刪除實例ID,如果手動調用FirebaseInstanceId.getInstance ().deleteInstanceId();我期待生成一個新的令牌,但在這種情況下實際上並沒有發生任何事情,onTokenRefresh從不會被調用。 – WenChao

+1

爲什麼要將令牌保存爲共享首選項 - 如果您可以調用[FirebaseInstanceId.getInstance().getToken()](https://firebase.google.com/docs/reference/android/com/google/firebase/iid/FirebaseInstanceId )在任何時候獲得它的價值? –

+0

@WenChao確保你通過'InstanceID.getInstance(this).deleteInstanceID()'調用了playservice的InstanceID,並從後臺線程調用它,在你成功刪除它之後,調用'InstanceID.getInstance(this).getID()生成新的令牌 – Salis

20

我有同樣的問題,像你這樣的。我的錯誤如下:我在AndroidManifest.xml文件中將<service>標籤放在<application>標籤之外。

現在我的是這樣的:

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 

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

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

和它的作品沒有任何問題。

+1

積分去到這個線程:http://stackoverflow.com/questions/37351354/firebase-cloud-messaging-notification-not-received-by-device – viplezer

+0

偉大的答案......這是獲取返回的Facebook ID ?.......因爲我試圖做到這一點,我得到一個非常大的代幣 – Juan

+0

Facebook?火力地堡?您在FirebaseInstanceIDService子類的onTokenRefresh方法中獲取Firebase雲消息傳遞的標記,並且是,它是一個長字符串,我的標記長度爲152個字符。 – viplezer

2
try { 
    FirebaseInstanceId.getInstance().deleteInstanceId(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

onCreate方法刪除標記。

+0

您是否嘗試過,它會拋出主線程異常的網絡.... –

+0

'線程t =新的線程()'將解決'MAIN_THREAD異常' – Pierre

11

是的,這可能會發生一些時間。

無論你想獲得你的fcm id,請致電以下方法。

try { 
      String refreshedToken = FirebaseInstanceId.getInstance().getToken(); 
      Log.d("Firbase id login", "Refreshed token: " + refreshedToken); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
+1

好的。幾次重新安裝後,令牌停止刷新,但直接getToken確實返回正確的令牌。 –

11

在我來說,我忘了添加Internet權限清單中,

<uses-permission android:name="android.permission.INTERNET" /> 

希望大多數人都不會犯這樣的錯誤。

10

嘗試重新安裝應用程序,先將其從您的設備或模擬器中卸載。它會生成一個新的標記,因此onTokenRefresh()將再次被調用。

1

在我的情況下,我嘗試了一切,但從未調用過onTokenRefresh。然後我改變我的WiFi和我連接到不同的網絡,現在它的工作!以前的WiFi具有良好的互聯網連接,不知道爲什麼發生。可能是這可以幫助某人。

1

重新安裝爲我做了伎倆!