firebase / flutterfire

🔥 A collection of Firebase plugins for Flutter apps.
https://firebase.google.com/docs/flutter/setup
BSD 3-Clause "New" or "Revised" License
8.46k stars 3.91k forks source link

[firebase_messaging] Crash when set onBackgroundMessage #125

Closed festelo closed 3 years ago

festelo commented 4 years ago

The following code causes immediate crash after app launching:

// Top Level. I also tried code from readme, no success.
Future<dynamic> myBackgroundMessageHandler(dynamic message) {
  return Future.value(0);
}

_firebaseMessaging.configure(
      onMessage: (d) async { print('on message'); handleMessage(d); },
      onBackgroundMessage: myBackgroundMessageHandler,
      onLaunch: (d) async { print('on launch'); handleMessage(d); },
      onResume: (d) async { print('on resume'); handleMessage(d); },
    );

If myBackgroundMessageHandler method isn't on top level, then it's not crashing, but throws null exception ("'toRawHandle' was called on null")

Without onBackgroundMessage: myBackgroundMessageHandler, all works fine.

Application.java class:

package com.protreal;

import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;

public class Application extends FlutterApplication implements PluginRegistrantCallback {
    @Override
    public void onCreate() {
        super.onCreate();
        FlutterFirebaseMessagingService.setPluginRegistrant(this);
    }

    @Override
    public void registerWith(PluginRegistry registry) {
        GeneratedPluginRegistrant.registerWith(registry);
    }
}

compileSdkVersion - 28 google-services version - 4.3.0

Crash log:

V/FA      (24891): Inactivity, disconnecting from the service
F/libc    (24891): Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1 in tid 24938 (Thread-3), pid 24891 (com.protreal)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Xiaomi/cepheus/cepheus:9/PKQ1.181121.001/V10.2.3.0.PFAMIXM:user/release-keys'
Revision: '0'
ABI: 'arm64'
pid: 24891, tid: 24938, name: Thread-3  >>> com.protreal <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1
Cause: null pointer dereference
    x0  0000000000000001  x1  0000007e86488660  x2  0000007e86400000  x3  0000000000000002
    x4  0000000000000088  x5  0000000000000000  x6  0000007e723beef0  x7  00000000000038c7
    x8  0000007e6abb7b60  x9  0000007e6abb7b60  x10 00000000000000e3  x11 0000000000000000
    x12 0000000000000003  x13 0000000000000010  x14 0020e0a7d87b2613  x15 0000007e723beef0
    x16 0000007f11519bd0  x17 0000007f1149ac28  x18 0000000000000010  x19 0000007e68c3b6e0
    x20 0000007e88844d40  x21 0000007e68227e60  x22 0000007e68227e90  x23 0000007e81778b98
    x24 000000000000003b  x25 0000007e723bf260  x26 0000007e723bf588  x27 000000000000003b
    x28 0000000000000001  x29 0000007e723bf3a0
    sp  0000007e723bf0f0  lr  0000007e73128078  pc  0000007e73124350
backtrace:
    #00 pc 0000000000d64350  /data/app/com.protreal-Sp4ZeyXWIfVaHXpYDtdueg==/lib/arm64/libflutter.so (offset 0xd50000)
    #01 pc 0000000000d68074  /data/app/com.protreal-Sp4ZeyXWIfVaHXpYDtdueg==/lib/arm64/libflutter.so (offset 0xd50000)
    #02 pc 0000000000d5fc0c  /data/app/com.protreal-Sp4ZeyXWIfVaHXpYDtdueg==/lib/arm64/libflutter.so (offset 0xd50000)
    #03 pc 0000000000d65f88  /data/app/com.protreal-Sp4ZeyXWIfVaHXpYDtdueg==/lib/arm64/libflutter.so (offset 0xd50000)
    #04 pc 0000000000d66664  /data/app/com.protreal-Sp4ZeyXWIfVaHXpYDtdueg==/lib/arm64/libflutter.so (offset 0xd50000)
    #05 pc 0000000000d65a88  /data/app/com.protreal-Sp4ZeyXWIfVaHXpYDtdueg==/lib/arm64/libflutter.so (offset 0xd50000)
    #06 pc 0000000000d6ac00  /data/app/com.protreal-Sp4ZeyXWIfVaHXpYDtdueg==/lib/arm64/libflutter.so (offset 0xd50000)
    #07 pc 0000000000014ff8  /system/lib64/libutils.so (android::Looper::pollInner(int)+836)
    #08 pc 0000000000014c18  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+60)
    #09 pc 00000000000122a4  /system/lib64/libandroid.so (ALooper_pollOnce+96)
    #10 pc 0000000000d6ab84  /data/app/com.protreal-Sp4ZeyXWIfVaHXpYDtdueg==/lib/arm64/libflutter.so (offset 0xd50000)
    #11 pc 0000000000d659d4  /data/app/com.protreal-Sp4ZeyXWIfVaHXpYDtdueg==/lib/arm64/libflutter.so (offset 0xd50000)
    #12 pc 0000000000d68ad8  /data/app/com.protreal-Sp4ZeyXWIfVaHXpYDtdueg==/lib/arm64/libflutter.so (offset 0xd50000)
    #13 pc 000000000009043c  /system/lib64/libc.so (__pthread_start(void*)+36)
    #14 pc 0000000000023c38  /system/lib64/libc.so (__start_thread+68)
Lost connection to device.

On Xiaomi Mi 9 (9.0.0) & Genymotion virtual device (7.1.0) (gservices installed)

oliwave commented 4 years ago

I'm having the same issue.

broberts-nybble commented 4 years ago

Any updates on this issue?

chrisurf commented 4 years ago

I'm having the same issue

ChrisOwen101 commented 4 years ago

I'm having a related issue here: https://github.com/FirebaseExtended/flutterfire/issues/144

droidluv commented 4 years ago

Yup its definitely crashing

divan commented 4 years ago

+1, crashing for me as well

AymanMubark commented 4 years ago

+1 For me as well

billymahmood commented 4 years ago

Same issue

[✓] Flutter (Channel stable, v1.9.1+hotfix.4, on Mac OS X 10.15 19A583, locale en-GB)

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3) [✓] Xcode - develop for iOS and macOS (Xcode 11.0) [✓] Android Studio (version 3.5) [✓] VS Code (version 1.38.1) [✓] Connected device (2 available)

• No issues found!

broberts-nybble commented 4 years ago

is this ever going to get fixed?

weizhongshen commented 4 years ago

+1, Same issue

bthuan commented 4 years ago

I have the same issue, but when i switch flutter channel to beta ( according to this: https://github.com/FirebaseExtended/flutterfire/issues/144) then there's no crash anymore

masinamichele commented 4 years ago

Same issue here

febg11 commented 4 years ago

same

kleinpetr commented 4 years ago

same

digarahayu commented 4 years ago

got same issue.. any update for fix this issue...?

iapicca commented 4 years ago

https://github.com/mwaylabs/flutter-apns/issues/4 https://github.com/FirebaseExtended/flutterfire/issues/840

rlsutton1 commented 4 years ago

same problem here

BansookNam commented 4 years ago

same problem. It's critical bug.

iampopal commented 4 years ago

same problem here, when app starts it crushes. there is no error or something in debug to know what is wrong. waiting for solution.

garmashev commented 4 years ago

same problem here

RoyGuanyu commented 4 years ago

Same problem, but I got error when I called ' await FirebaseMessaging().getToken() ' signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1 Cause: null pointer dereference ...

doxtitech commented 4 years ago

Same problem as the main thread.NoSuchMethodError: The method 'toRawHandle' was called on null.

RoyGuanyu commented 4 years ago

p.s. Setting onBackgroundMessage in FirebaseMessaging().configure lead to crash, if without setting onBackgroundMessage, no crash occurs.

Same problem, but I got error when I called ' await FirebaseMessaging().getToken() ' signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1 Cause: null pointer dereference ...

charleshan commented 4 years ago

Instead of making a new comment, please upvote (👍) the main post to let the team know that you're also experiencing the issue.

gabrielginter commented 4 years ago

After fiddling with Firebase for flutter I realize you will get this error if you don't set "android:name" to ".Application" in the "application" node in the AndroidManifest.xml file:

image

BUT..... Be aware that there seems to be another issue that causes the app to crash when the notification is received, such error seems to be fixed when using Flutter master channel, according to what I've read, give it a try and let us know.

kentcb commented 4 years ago

@gabrielginter That wasn't the problem for me (and I'd imagine many others here). I have .Application but it still crashes immediately on startup.

aleaforny commented 4 years ago

I'm sorry to add kinda a useless input to this issue, but I'd just wanted to let you know that I'm now having this issue after upgrading the plugin to 6.0.1 (just released today) - I did not have it before.

FYI, my backgroundMessageHandler was STATIC declared inside a class, not a top-level function.

I guess it's related to the main issue, as I've had 'toRawHandle' was called on null exception in the very first place, too.

Does someone have an ETA on a fix, even approximative?

Eddydpyl commented 4 years ago

Same issue in iOS: https://github.com/FirebaseExtended/flutterfire/issues/1469

sarinupreti commented 4 years ago

same here . any updates ?

DyaryRaoof commented 4 years ago

same issue

koteezy commented 4 years ago

Resolving by change channel to master, but, some another packages not working correctly on master channel ¯_(ツ)_/¯

DyaryRaoof commented 4 years ago

Unfortunately I can't even switch to master , dev , or beta channel because of another bug in flutter android : https://github.com/flutter/flutter/issues/44796

we need a real solution.

koteezy commented 4 years ago

Guys, did you try call the messaging on top of you'r app?

I tried like this and it works for me ( so far. )

Both in dev mode and in release mode works fine now.

Future bgMsgHdl(Map<String, dynamic> message) async {
  print("onbgMessage: $message");
}

main() {
WidgetsFlutterBinding.ensureInitialized();

void firebaseMessagingHandler() {
messaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
},
onBackgroundMessage: bgMsgHdl,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
}

firebaseMessagingHandler();

messaging.getToken().then((v) {
print("Token!");
print(v);
});
setupDeviceUuid();
setupDatabase().then((db) => {runApp(MyApp())});
}
DyaryRaoof commented 4 years ago

Guys, did you try call the messaging on top of you'r app?

I tried like this and it works for me ( so far. )

Both in dev mode and in release mode works fine now.

Future bgMsgHdl(Map<String, dynamic> message) async {
  print("onbgMessage: $message");
}

main() {
WidgetsFlutterBinding.ensureInitialized();

void firebaseMessagingHandler() {
messaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
},
onBackgroundMessage: bgMsgHdl,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
}

firebaseMessagingHandler();

messaging.getToken().then((v) {
print("Token!");
print(v);
});
setupDeviceUuid();
setupDatabase().then((db) => {runApp(MyApp())});
}

this Doesn't work for me.

Eddydpyl commented 4 years ago

Resolving by change channel to master, but, some another packages not working correctly on master channel ¯(ツ)

Nor does this work for me. Though my problem is with iOS #1469. I've seen it mentioned as a solution in another issue, and it has a few likes https://github.com/FirebaseExtended/flutterfire/issues/144#issuecomment-538775382. It may very well fix the problem in Android devices, but not in iOS.

DyaryRaoof commented 4 years ago

@Eddydpyl I have set myBackGroundMessagingHandler to null oniOS. you don't need the handler on iOS. I have set it this way :

 onBackgroundMessage:
          Platform.isAndroid ? myBackgroundMessageHandler : null,

and it works perfectly fine. I receive notifications when app is in background , terminated, or in foreground.

Eddydpyl commented 4 years ago

@DyaryRaoof how do I handle data messages in iOS then? I don't want the notification, just the data payload, which is why I'm setting onBackgroundMessage instead of onMessage, onLaunch or onResume.

DyaryRaoof commented 4 years ago

@Eddydpyl You get the payload as part of the message variable that you have setup when you configured fireBase. for example :

_fcm.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
             String payload = message['data'];
      },
      onBackgroundMessage:
          Platform.isAndroid ? myBackgroundMessageHandler : null,
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
              String payload = message['data'];
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");

              String payload = message['data'];
      },
    );

print the message variable see if you have 'data' as part of the JSON.

Eddydpyl commented 4 years ago

@DyaryRaoof I do, but I failed to mention that I need that data in the background. On Android, using onBackgroundMessage I'm able to process said data wether the app is in the foreground or not, but on iOS the onMessage callback only triggers after I reopen the app.

naumanmir commented 4 years ago

@Eddydpyl can you please tell how are you able to get messages in background on Android.? My app is crashing at startup with background message handler set. I am even configuring it as a top level function. Where are you configuring it. Can you help please?

Eddydpyl commented 4 years ago

@naumanmir I wish... I'm not doing anything special, and I haven't actually tested it on any of the phone models that people are reporting it's not working on. Furthermore, there's this issue that popped up (https://github.com/FirebaseExtended/flutterfire/issues/1709). You can find some more details on how I'm doing things there, but again, it's nothing special.

About iOS, I never got it to work, though I assume that it has more to do with a limitation of the OS than a bug on this library's part.

bparrishMines commented 4 years ago

Hi @festelo

It seems people are still experiencing this crash.

Have you tried the same code on a different virtual device? I attempted to reproduce this with a Pixel 3 API 28, 'com.android.tools.build:gradle:3.5.3', 'com.google.gms:google-services:4.3.0'.

But, I wasn't able to get it to crash when adding the onBackgroundMessageHandler. This may potentially be a crash from Firebase rather than Flutter.

I'm also assuming that you were able to receive messages in the foreground with the FirebaseMessaging.configure() onMessage callback?

DyaryRaoof commented 4 years ago

yes the crash is still there even with applying the classpath and using Pixel 3 API 28 Emulator. I also tried it on a real device (Samsung Galaxy 7) the same issue occurs. Tried it on stable and master branch the same issue is there.

SebastienMelki commented 4 years ago

Hey everyone, did anybody figure out a solution for this? App crashes as soon as notification is received when onBackgroundMessage is enabled. Without it everything works fine. But then this means that I can't process notifications when app is terminated. I can just run code onLaunch. Which beats the purpose of onBackgroundMessage. Is it just not working ?

DyaryRaoof commented 4 years ago

no nothing up to now

singun-lxd commented 4 years ago

seemed like flutter framework bug

Gyoko commented 4 years ago

Followed official tutorial with up-to-date everything. Issue is still present - I receive notifications properly and everything but onBackgroundMessage is working

sakinaboriwala commented 4 years ago

Guys, even after so many upvotes and frustrations nobody from the team is taking this seriously, I really don't understand how two Google products have so much incompatibility. It was so much smoother to configure Push Notifications with React native than it has been for Flutter.

The Documentation is completely outdated, there is not mention of Kotlin related changes anywhere. And even if you somehow manage to get it working as soon as you add the onBackroundMessage function the App crashes with absolutely no error. I am on OnePlus 5T device.

Please give some kind of conclusion or assurance or solution. Something. It's been a week almost since I have been trying this. This should be a very straightforward configuration IMO. It's not even an edge case. Everyone is going to need Background messaging at some point in their Application Development Cycle.

drikanius commented 4 years ago

First and foremost I would like to say that I agree with @sakina1403 . It drives crazy how something as important as notification can be so messy and frustrating.

I managed, somehow, to make firebase_massage work. It's not the best solution (and really verbose) but I'll share it as it can solve someone's problem.

Assuming that firebase cloud with the basic notification is working (onMessage, onLaunch, onResume), and that I work on 1.18.0-9.0.pre.38 (master), I'll try to focus on onBackgroundMessage (which caused me more headaches).

Also, I used flutter_local_notification to display messages (also needed some plugin registration to make it work).

As in all comments reported, 'onBackgroundMessage' needs a static function to work (or top level). In my case, I implemented 'myBackgroundMessageHandler'.

FirebaseMessaging configure:

    _messaging.configure(
      onMessage: (message) async {
        _notification.show(0, 'title', 'onMessage body', NotificationDetails(
          AndroidNotificationDetails(
              'id',
              'name',
              'description'
          ),
          IOSNotificationDetails(),
        ));
        print('... onMessage: $message');
      },
      onLaunch: (message) async {
        print('.. onLaunch: $message');
      },
      onResume: (message) async {
        print('. onResume: $message');
      },
      onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
    );

  static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
    print('AppPushs myBackgroundMessageHandler : $message');
    _showNotification('background title', 'background body');
    return Future<void>.value();
  }

Not much mystery so far. But that part was what made everything stop working.

In 'android/app/src/main/java/' (where are folders I created, eg com/example/my_notification_test, - same path that appears in AndroidManifest.xml at 'package')

After creating these folders I created 3 files: 'Application.java', 'FirebaseCloudMessagingPluginRegistrant.java', and 'FlutterLocalNotificationPluginRegistrant.java'.

package <your package here, the same path that appears in AndroidManifest.xml at 'package')>;

import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;

public class Application extends FlutterApplication implements PluginRegistrantCallback {

    @Override
    public void onCreate() {
        super.onCreate();
        FlutterFirebaseMessagingService.setPluginRegistrant(this);
    }

    @Override
    public void registerWith(PluginRegistry registry) {
        FirebaseCloudMessagingPluginRegistrant.registerWith(registry);
        FlutterLocalNotificationPluginRegistrant.registerWith(registry);
    }
}
package <your package here,  same path that appears in AndroidManifest.xml at 'package')>;

import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;

public final class FirebaseCloudMessagingPluginRegistrant{
    public static void registerWith(PluginRegistry registry) {
        if (alreadyRegisteredWith(registry)) {
            return;
        }
        FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
    }

    private static boolean alreadyRegisteredWith(PluginRegistry registry) {
        final String key = FirebaseCloudMessagingPluginRegistrant.class.getCanonicalName();
        if (registry.hasPlugin(key)) {
            return true;
        }
        registry.registrarFor(key);
        return false;
    }
}
package <your package here,  same path that appears in AndroidManifest.xml at 'package')>;

import io.flutter.plugin.common.PluginRegistry;
import com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin;

public final class FlutterLocalNotificationPluginRegistrant{

    public static void registerWith(PluginRegistry registry) {
        if (alreadyRegisteredWith(registry)) {
            return;
        }
        FlutterLocalNotificationsPlugin.registerWith(registry.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"));
    }

    private static boolean alreadyRegisteredWith(PluginRegistry registry) {
        final String key = FlutterLocalNotificationPluginRegistrant.class.getCanonicalName();
        if (registry.hasPlugin(key)) {
            return true;
        }
        registry.registrarFor(key);
        return false;
    }
}

In AndroidManifest.xml I changed android:name to ".Application":

    <application
        android:name=".Application"

And I've added permission on top of the tag <application. More like this:

    <uses-permission android:name="android.permission.VIBRATE" />
    <application
        android:name=".Application"

Finally my _showNotification(...) function:

  static Future _showNotification(String title, String message) async {
    print('test...');

    var initializationSettingsAndroid = AndroidInitializationSettings('launcher');
    var initializationSettingsIOS = IOSInitializationSettings(
        onDidReceiveLocalNotification: (id, title, body, payload) {
          print('onDidReceiveLocalNotification');
          return null;
        });

    var initializationSettings = InitializationSettings(
        initializationSettingsAndroid, initializationSettingsIOS);

    FlutterLocalNotificationsPlugin notification = FlutterLocalNotificationsPlugin();

    await notification.initialize(initializationSettings,
        onSelectNotification: (payload) {
          print('onDidReceiveLocalNotification');
          return null;
        });

    var androidPlatformChannelSpecifics = AndroidNotificationDetails(
        'id',
        'name',
        'description'
    );

    var platformChannelSpecifics = NotificationDetails(
        androidPlatformChannelSpecifics,
        IOSNotificationDetails()
    );
    notification.show(
      0,
      '$title',
      '$message',
      platformChannelSpecifics,
      payload: 'Default_Sound',
    );
  }

The code is not organized, but this is more or less what I did to work.

I hope I've helped

joshipucher commented 4 years ago

@drikanius your solution made it not crash anymore for me! But I still don't get any notifications for android when the app is terminated. It only works when the app is still in the background, which already worked before.