Debug School

rakesh kumar
rakesh kumar

Posted on

How to give Notification Permission in Mobile Apps using firebase

What is Notification Permission

What is Notification Permission?

Notification permission is the authorization given by the user to allow an app to:

✔ Show push notifications
✔ Display banners, alerts, and pop-ups
✔ Play notification sounds
✔ Show badges on the app icon
✔ Deliver critical alerts (iOS only)

Most operating systems treat notifications as privacy-sensitive features.
Because of this, they require explicit user consent before an app can send or display notifications.

When your app needs notification access, you call a function inside your notification service class, usually named:

requestNotificationPermission()
Enter fullscreen mode Exit fullscreen mode

==============or=============

final NotificationServices _notificationServices = NotificationServices();
_notificationServices.requestNotificationPermission();
Enter fullscreen mode Exit fullscreen mode
import 'package:firebase/notification_services.dart';
import 'package:flutter/material.dart';


class HomeScreen extends StatefulWidget {
  final String title;

  const HomeScreen({super.key, required this.title});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _counter = 0;

  // Create Notification Service Instance
  final NotificationServices _notificationServices = NotificationServices();

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

    // Request permission on app start
    _notificationServices.requestNotificationPermission();

    // Initialize foreground notifications listener
    _notificationServices.firebaseInit(context);

    // Handle notification click when app is opened from notification
    _notificationServices.handleNotificationClick(context);

    // Optional: Print FCM Token
    _notificationServices.getDeviceToken();
  }
Enter fullscreen mode Exit fullscreen mode

This function internally triggers:

🔹 The OS permission dialog
🔹 Firebase Messaging authorization
🔹 Permission statuses (authorized / denied / provisional)

Why Do Apps Need Notification Permission?

Here are the key reasons:

  1. Respecting User Privacy

Users should have full control over which apps can interrupt them with alerts.

  1. Preventing Notification Spam

Without permission control, apps could misuse notifications and annoy users.

  1. OS Policy Requirements

Android 13+ and iOS require apps to request permission before sending notifications.
If the user denies it → notifications will NOT appear.

  1. Compliance with Play Store & App Store guidelines

Both Google & Apple enforce strict rules about permission usage.

  1. Better User Engagement

An app that politely requests permission usually gets a higher approval rate.

📱

Notification Permission on Android

Android ≤ 12

Notifications are allowed by default, unless the user disables them manually.

Android 13+ (API 33+)

Google introduced the POST_NOTIFICATIONS runtime permission.
Apps must explicitly request permission, similar to camera or location.

If permission is not granted:

❌ Firebase messages will not show
❌ Foreground notifications won't appear
❌ No banner, sound, or alerts

🍎

Notification Permission on iOS

Apple requires notification permission for all iOS versions.

When your app requests permission, the user sees a system popup like:

“App wants to send you notifications”
Allow / Don't Allow

If the user denies:

❌ All notifications are blocked
❌ App cannot ask again (unless user changes settings manually)

That’s why a well-designed permission request strategy is very important.

🧠

Best Practices for Asking Notification Permission

✔ Ask permission after explaining why (not on app launch)
✔ Trigger the request after a meaningful user action
✔ Show a custom screen before the first system popup
✔ If denied → redirect user to system settings screen
✔ Never spam the permission dialog

Syntax to Request Notification Permission (Flutter)

Before using it inside your UI, you must understand the syntax:

🔹 Syntax

_notificationServices.requestNotificationPermission();
Enter fullscreen mode Exit fullscreen mode

This means:

_notificationServices → an object of your NotificationServices class

requestNotificationPermission() → a method inside that class

It triggers the notification permission popup

It handles authorized / provisional / denied cases

📌

When Should You Call It?

You typically call it inside initState():

When the Home Screen loads

Or after a user performs a meaningful action

Do NOT call it immediately on app launch (user may deny it).

  void initState() {
    super.initState();

    // Request permission on app start
    _notificationServices.requestNotificationPermission();

    // Initialize foreground notifications listener
    _notificationServices.firebaseInit(context);

    // Handle notification click when app is opened from notification
    _notificationServices.handleNotificationClick(context);

    // Optional: Print FCM Token
    _notificationServices.getDeviceToken();
  }

Enter fullscreen mode Exit fullscreen mode

Example (After Theory)

Now that we understand why permission is needed and what the syntax is, here is how you usually place it inside a Stateful widget:

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

  // Asking notification permission
  _notificationServices.requestNotificationPermission();
}
Enter fullscreen mode Exit fullscreen mode

Full code

Step 1: Import Dependencies

Add this to your pubspec.yaml:

dependencies:
  firebase_core: ^3.0.0
  firebase_messaging: ^15.0.0
  app_settings: ^5.1.1
Enter fullscreen mode Exit fullscreen mode

Run:

flutter pub get

📌 Step 2: Create Notification Service Class

Create a file:

lib/notification_services.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:app_settings/app_settings.dart';

class NotificationServices {
  final FirebaseMessaging _messaging = FirebaseMessaging.instance;

  /// REQUEST PERMISSION
  Future<void> requestNotificationPermission() async {
    NotificationSettings settings = await _messaging.requestPermission(
      alert: true,
      announcement: true,
      badge: true,
      carPlay: false,
      criticalAlert: true,
      provisional: true,
      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 denied permission");
      AppSettings.openAppSettings(type: AppSettingsType.notification);
    }
  }

  /// GET FCM TOKEN
  Future<String?> getDeviceToken() async {
    String? token = await _messaging.getToken();
    print("FCM Token: $token");
    return token;
  }

  /// HANDLE FOREGROUND NOTIFICATIONS
  void firebaseInit(BuildContext context) {
    FirebaseMessaging.onMessage.listen((message) {
      if (message.notification != null) {
        _showPopup(
          context,
          message.notification!.title ?? "Notification",
          message.notification!.body ?? "",
        );
      }
    });
  }

  void _showPopup(BuildContext context, String title, String body) {
    showDialog(
      context: context,
      builder: (_) => AlertDialog(
        title: Text(title),
        content: Text(body),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text("OK"),
          )
        ],
      ),
    );
  }

  /// HANDLE CLICK EVENTS
  void handleNotificationClick(BuildContext context) {
    FirebaseMessaging.onMessageOpenedApp.listen((message) {
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (_) => NotificationClickScreen(
            title: message.notification!.title ?? "",
            body: message.notification!.body ?? "",
          ),
        ),
      );
    });
  }
}

class NotificationClickScreen extends StatelessWidget {
  final String title;
  final String body;

  const NotificationClickScreen({
    super.key,
    required this.title,
    required this.body,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Notification Details")),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text("Title: $title",
                style: const TextStyle(
                    fontSize: 20, fontWeight: FontWeight.bold)),
            const SizedBox(height: 10),
            Text("Body: $body", style: const TextStyle(fontSize: 18)),
          ],
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

📌 Step 3: Use Notification Service in HomeScreen

Update your HomeScreen:

class _HomeScreenState extends State<HomeScreen> {
  final NotificationServices _notificationServices = NotificationServices();

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

    _notificationServices.requestNotificationPermission();
    _notificationServices.firebaseInit(context);
    _notificationServices.handleNotificationClick(context);
    _notificationServices.getDeviceToken();
  }
}
Enter fullscreen mode Exit fullscreen mode

📌 Step 4: Initialize Firebase in main.dart

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  await FirebaseApi().initNotifications(); // optional background handler

  runApp(const MyApp());
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)