38

I'm trying to send notifications from an Node.js API to a Flutter application. First, I want to make my application able to receive notifications from Firebase.

But, when I initializeApp, I got an issue :

PlatformException (PlatformException(null-error, Host platform returned null value for non-null return value., null, null))

and this, in the console:

E/flutter (25357): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: PlatformException(null-error, Host platform returned null value for non-null return value., null, null)
E/flutter (25357): #0      FirebaseCoreHostApi.optionsFromResource (package:firebase_core_platform_interface/src/pigeon/messages.pigeon.dart:250)
package:firebase_core_platform_interface/…/pigeon/messages.pigeon.dart:1
E/flutter (25357): <asynchronous suspension>
E/flutter (25357): #1      MethodChannelFirebase.initializeApp (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:89)
package:firebase_core_platform_interface/…/method_channel/method_channel_firebase.dart:1
E/flutter (25357): <asynchronous suspension>
E/flutter (25357): #2      Firebase.initializeApp (package:firebase_core/src/firebase.dart:40)
package:firebase_core/src/firebase.dart:1
E/flutter (25357): <asynchronous suspension>
E/flutter (25357): #3      main (package:notifappfcm/main.dart:13)
package:notifappfcm/main.dart:1

I've been looking for a solution to this problem, but I really can't find it.

This is my application code:

main.dart

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'mainscreen.dart';

Future<void> _firebadeMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(); // options: DefaultFirebaseConfig.platformOptions
  print('Handling a background message ${message.messageId}');
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  FirebaseMessaging.onBackgroundMessage(_firebadeMessagingBackgroundHandler);

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MainScreen(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

 
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

 @override
  void initState() {
    super.initState();
  }

  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

mainscreen.dart

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

class MainScreen extends StatefulWidget {
  const MainScreen({Key? key}) : super(key: key);

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  late AndroidNotificationChannel channel;
  late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;

  @override
  void initState() {
    super.initState();

    requestPermission();
    loadFCM();
    listenFCM();
    // Get device's notification token
    getToken();
  }


  void getToken() async {
    await FirebaseMessaging.instance.getToken().then((token) => print(token));
  }

  void requestPermission() async {
    FirebaseMessaging messaging = FirebaseMessaging.instance;

    NotificationSettings settings = await messaging.requestPermission(
      alert: true,
      announcement: false,
      badge: true,
      carPlay: false,
      criticalAlert: false,
      provisional: false,
      sound: true,
    );

    if (settings.authorizationStatus == AuthorizationStatus.authorized) {
      print('User granted permission');
    } else if (settings.authorizationStatus ==
        AuthorizationStatus.provisional) {
      print('User granted provisional permission');
    } else {
      print('User declined or has not accepted permission');
    }
  }

  void listenFCM() async {
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      RemoteNotification? notification = message.notification;
      AndroidNotification? android = message.notification?.android;
      if (notification != null && android != null && !kIsWeb) {
        flutterLocalNotificationsPlugin.show(
            notification.hashCode,
            notification.title,
            notification.body,
            NotificationDetails(
                android: AndroidNotificationDetails(channel.id, channel.name,
                    // ignore: todo
                    // TODO add a proper drawable resource to android (now using one that already exists)
                    icon: 'launch_background')));
      }
    });
  }

  void loadFCM() async {
    if (!kIsWeb) {
      channel = const AndroidNotificationChannel(
        'high_importance_channel', // id
        'High Importance Notifications', // title
        importance: Importance.high,
        enableVibration: true,
      );

      flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

      /// Create an Android Notification Channel.
      ///
      /// We use this channel in the `AndroidManifest.xml` file to override the
      /// default FCM channel to enable heads up notifications.
      await flutterLocalNotificationsPlugin
          .resolvePlatformSpecificImplementation<
              AndroidFlutterLocalNotificationsPlugin>()
          ?.createNotificationChannel(channel);

      /// Update the iOS foreground notification presentation options to allow
      /// heads up notifications.
      await FirebaseMessaging.instance
          .setForegroundNotificationPresentationOptions(
        alert: true,
        badge: true,
        sound: true,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: Container(
        height: 40,
        width: 200,
        color: Colors.red,
      ),
    ));
  }
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Shiroe
  • 497
  • 1
  • 4
  • 9
  • having the same issues any fix – segun code Jul 07 '22 at 20:52
  • I found an issue, I just had to proprely link my application with firebase. It was wrong when I did it the first time. This is a link you can follow to help you link your application and your FCM : https://firebase.google.com/docs/flutter/setup?platform=android PS : follow the full tutorial, i didn't at the very first time and this is why i get errors ^^ – Shiroe Jul 08 '22 at 07:36
  • What do you mean by properly link . Can you be more specific – krishnaacharyaa Jul 08 '22 at 07:38
  • To make your application able to communicate with Firebase, u have to register your app in Firebase. So, I folloed the entier tutorial on firebase.google.com/docs/flutter/setup?platform=android and my code was working after it. The mistake I've done was to only do the first part of the tutorial (didn't see the next ones), and my application wasn't linked with Firebase. – Shiroe Jul 08 '22 at 11:35
  • Inn my case ,I do flutter clean and its working fine – Rahul Kushwaha Feb 21 '23 at 10:25

12 Answers12

66

Make sure you have added the Firebase SDK dependencies in the Project Level build.gradle file and Application Level build.gradle file

Dependencies to be added in Project Level build.gradle:

buildscript {
  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
  }
  dependencies {
    ...
    // Add this line
    classpath 'com.google.gms:google-services:4.3.13'
  }
}

allprojects {
  ...
  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
    ...
  }
}

Dependencies to be added in App Level build.gradle:

apply plugin: 'com.android.application'
// Add this line
apply plugin: 'com.google.gms.google-services'

dependencies {
  // Import the Firebase BoM
  implementation platform('com.google.firebase:firebase-bom:30.2.0')

  // Add the dependency for the Firebase SDK for Google Analytics
  // When using the BoM, don't specify versions in Firebase dependencies
  implementation 'com.google.firebase:firebase-analytics'

  // Add the dependencies for any other desired Firebase products
  // https://firebase.google.com/docs/android/setup#available-libraries
}
Martin Braun
  • 10,906
  • 9
  • 64
  • 105
Darsh Shah
  • 675
  • 4
  • 4
12

Make sure you have these settings in your android/build.gradle

buildscript {

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
  }

  dependencies {
    // ...

    // Add the following line:
    classpath 'com.google.gms:google-services:4.3.13'  // Google Services plugin
  }
}

allprojects {
  // ...

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
    // ...
  }
}

And then in your android/app/build.gradle:

apply plugin: 'com.android.application'
// Add the following line:
apply plugin: 'com.google.gms.google-services'  // Google Services plugin

android {
  // ...
}

You can follow the steps here

And don't forget to download google-service.json from firebase project console, and put it into android/app folder.

Kurt
  • 678
  • 1
  • 7
  • 24
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/32468233) – Lalaluka Aug 18 '22 at 14:48
  • @Lalaluka Thanks for reminding. I've modified. – Kurt Aug 19 '22 at 06:13
7

Attention. Manually changing build.gradle files as described above is not a solution. It will either won't work or every build will generate lots of warnings as using deprecated dependencies. Correct solution is this: Firabase should be intialiezed like below:

await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);

For this, you will need to run some commands from command line / terminal:

// Add firebase core into your project
flutter pub add firebase_core
// Generate firebase options file
flutterfire configure
// Import firebase core and generated file
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

For details you can refer here.

Elmar
  • 2,235
  • 24
  • 22
  • I was missing `options: DefaultFirebaseOptions.currentPlatform` in my `Firebase.initializeApp` in my main() function in main.dart. After adding this (and importing the `firebase_options.dart` file that gets created with `flutterfire configure` in the terminal), it worked. – Boommeister Sep 15 '22 at 12:39
  • All of the above solutions for modifying `build.gradle` did not work for me. However, this solution of adding `options: DefaultFirebaseOptions.currentPlatform` inside `Firebase.initializeApp` worked for me. – Asad Aug 23 '23 at 21:47
5

Sometimes FlutterFire cli is not able to update build.gradle files so you get the above error

in project level build.gradle add the firebase dependencies as

   dependencies {
    classpath 'com.android.tools.build:gradle:7.1.2'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    classpath 'com.google.gms:google-services:4.3.10'
    classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
}

in app level build.gradle file apply firebase plugins as

    apply plugin: 'com.google.gms.google-services'
    apply plugin: 'com.google.firebase.crashlytics'
IonicFireBaseApp
  • 925
  • 3
  • 10
2

From:

await Firebase.initializeApp();

To:

await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

Works for me!

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
1

The accepted answer still definitely works, but it requires manual operations plus the uncertainty of which Google Services version and Firebase BOM to add.

I recommend using the FlutterFire CLI to configure the project and to automatically set up all these build.gradle dependencies.

Official configuration setup can be found here.

PaianuVlad23
  • 1,751
  • 2
  • 13
  • 16
1

It looks like you need to set the DefaultFirebaseOptions in await Firebase.initializeApp(); line.

According to this docs, you need to put the options.

Follow this step by step

  1. Run flutter pub add firebase_core
  2. Run flutterfire configure. Skip this if you already configure your project.
  3. In your main.dart, update this in your code.

From

await Firebase.initializeApp();

To

await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  1. Try running your application

I hope this helps to solve this issue.

Thank you for reading!

1

This Solution is effective :)

in project level build.gradle add the firebase dependencies as

dependencies {

    classpath 'com.android.tools.build:gradle:7.1.2'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    classpath 'com.google.gms:google-services:4.3.10'
    classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
}

in app level build.gradle file apply firebase plugins as

apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
0

If you are configuring flutter in ios make sure to initilize this in swift file FirebaseApp.configure()

import FirebaseCore //import this on top

0

In my case, to solved this issue, I checked the registration app process and I have missed to add this line:

at the level app's build.grade:

apply plugin: 'com.google.gms.google-services'

I added this dependencies too: implementation 'com.google.firebase:firebase-auth-ktx' for authentication.

Regards.

Jesus

0

I had both my Ethernet and WiFi connected. What solved it for me was to disconnect my Ethernet cable and only use WiFi.

0

After long search I found appropriate solution for me (the same issue): simple you need "to connect" your project to firebase.

Try this from step 1 - 3: https://firebase.google.com/docs/flutter/setup?platform=android

I'll be glad if it's useful to someone.