Description
Note: This issue could be Android specific, I didn't test it on iOS yet.
The behavior of firebaseMessaging.getToken()
is mysterious.
I am facing a problem where firebaseMessaging.getToken()
no longer returns anything, thus await firebaseMessaging.getToken()
will block forever. I'm quite sure that the code worked before. I tried to figure out why, but no luck so far - the code behaves differently on Java and Flutter side.
Here's the details.
There's nothing special on the initialization of firebaseMessaging
, I'm posting it here anyway:
final FirebaseMessaging firebaseMessaging = new FirebaseMessaging();
firebaseMessaging.configure(onMessage: (Map<String, dynamic> message) async {
print('OnMessage');
print(message);
}, onLaunch: (Map<String, dynamic> message) {
print('onLaunch()');
}, onResume: (Map<String, dynamic> message) {
print('onResume()');
});
firebaseMessaging.requestNotificationPermissions();
The problem is at the firebaseMessaging.getToken()
call, which never returns a token and blocks forever:
String fcmToken = await firebaseMessaging.getToken();
This had happened before, but was kind of "resolved" by moving the above line later at my app's init stage. Today it happened again, and I decided to try to figure out the cause.
So I opened the Java project, added the following code (copied from the Firebase's example), had it called from Flutter through platform channel, to see if I could see a more verbose error output by retrieving the token manually (bypassing the firebaseMessaging plugin).
...
if (call.method.equals("getFCMToken")) {
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
@Override
public void onComplete(@NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = task.getResult().getToken();
// Log and toast
String msg = "Token: "+ token;
Log.d(TAG, msg);
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
}
...
In Flutter, I added this getFCMToken()
call BEFORE firebaseMessaging.getToken()
. To my surprise, this getFCMToken()
finishes almost immediately with an FCM token, no error! But the subsequent firebaseMessaging.getToken()
still blocks forever!
So I set some breakpoints in the java files of the firebase messaging plugin, and found that broadcastToken()
was not called at all. This is strange.
Not knowing what happened, I uninstalled the app and run it again (still on the Java side). This time broadcastToken()
is called, which is invoked from this line! As a matter of course, firebaseMessaging.getToken()
returns the FCM token successfully.
Then I switched to the Flutter side and run my project again hoping to see the issue "fixed" and boom! getFCMToken()
succeeded but firebaseMessaging.getToken()
still failed!
Then I went back to the Java side, hoping that it would fail again so that I would know why the code under the "configure" method call isn't running. Unfortunately, the code in Java side worked correctly!
Then I went back to the Flutter side, ran flutter clean
, and rerun the code. Still fails on firebaseMessaging.getToken()
.
Now I am in a situation where the same code is acting differently when compiled in "Flutter mode" and "Android mode". I feel really frustrated because it seems impossible to track the cause of the issue.
[√] Flutter (Channel dev, v0.5.7, on Microsoft Windows [Version 10.0.17134.165], locale zh-HK)
• Flutter version 0.5.7 at C:\flutter
• Framework revision 66091f9696 (4 weeks ago), 2018-07-09 12:52:41 -0700
• Engine revision 6fe748490d
• Dart version 2.0.0-dev.63.0.flutter-4c9689c1d2
[√] Android toolchain - develop for Android devices (Android SDK 27.0.3)
• Android SDK at C:\Users\CY\AppData\Local\Android\sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-27, build-tools 27.0.3
• Java binary at: C:\Program Files\Android\Android Studio 3\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b02)
• All Android licenses accepted.
[!] Android Studio (version 3.0)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin version 22.2.1
• Dart plugin version 171.4424
X Unable to determine bundled Java version.
• Try updating or re-installing Android Studio.
[√] Android Studio (version 3.1)
• Android Studio at C:\Program Files\Android\Android Studio 3
• Flutter plugin version 27.1.1
• Dart plugin version 173.4700
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b02)
[!] Android Studio (version 2.1)
• Android Studio at C:\Android\android-studio
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
X Unable to find bundled Java version.
• Try updating or re-installing Android Studio.
[!] VS Code, 64-bit edition (version 1.23.0)
• VS Code at C:\Program Files\Microsoft VS Code
• Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[√] Connected devices (1 available)
• Nexus 5X • 00e1c63e154fae10 • android-arm64 • Android 8.1.0 (API 27)
! Doctor found issues in 3 categories.
Addendum: To temporary work around this issue, I modified my platform channel code as follow, and have it called before firebaseMessaging.getToken()
.
...
if (call.method.equals("getFCMToken")) {
FlutterFirebaseInstanceIDService.broadcastToken(MainActivity.this);
}
...
This seems to overcome the issue that broadcastToken
isn't called from the plugin code. But of course this can't be a solution. Also not tested on iOS.