firebase_easy_notify 1.0.0 copy "firebase_easy_notify: ^1.0.0" to clipboard
firebase_easy_notify: ^1.0.0 copied to clipboard

The easiest way to handle Firebase Cloud Messaging + Local Notifications + Timezone-aware scheduling in Flutter (Android & iOS)

πŸ”” Firebase Easy Notify #

The easiest way to handle Firebase Cloud Messaging + Local Notifications + Timezone-aware scheduling in Flutter

Set up fully working notifications (FCM push + local scheduled reminders) for both Android and iOS with just 3-5 lines of code.

pub package License: MIT


✨ Features #

  • πŸš€ Super Simple API - Just call EasyNotify.init() and you're ready
  • πŸ“± FCM Integration - Firebase Cloud Messaging with automatic foreground handling
  • ⏰ Smart Scheduling - Timezone-aware weekly/batch/one-time notifications
  • 🌍 Timezone Support - Automatically handles user's local timezone
  • πŸ“’ Topic Management - Easy subscribe/unsubscribe with user type helpers
  • 🎯 Batch Scheduling - Schedule multiple notifications at once
  • πŸ”” Tap Handling - Built-in callbacks for notification interactions
  • πŸ“Š Debug Friendly - Comprehensive logging with [EasyNotify] prefix
  • 🎨 Production Ready - Clean architecture, error handling, and best practices

πŸ“¦ Installation #

Add to your pubspec.yaml:

dependencies:
  firebase_easy_notify: ^1.0.0
  firebase_core: ^2.24.2  # Required for Firebase initialization

That's it! Firebase Easy Notify exports all the types you need (RemoteMessage, NotificationResponse, etc.) so you don't need to add firebase_messaging or flutter_local_notifications separately.

Run:

flutter pub get

Note: If you previously had firebase_messaging or flutter_local_notifications in your dependencies, you can safely remove them. EasyNotify manages these internally and exports the necessary types.


πŸš€ Quick Start #

1. Initialize (in main.dart) #

import 'package:firebase_core/firebase_core.dart';
import 'package:easy_notify/easy_notify.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Initialize Firebase
  await Firebase.initializeApp();
  
  // Initialize EasyNotify
  await EasyNotify.init(
    androidIcon: '@mipmap/ic_launcher',
    requestPermissionOnInit: true,
    onNotificationTap: (response) {
      print('Notification tapped: ${response.payload}');
    },
    onMessageOpened: (message) {
      print('FCM message opened: ${message.data}');
    },
  );
  
  runApp(MyApp());
}

2. Show Immediate Notification #

EasyNotify.show(
  title: 'Hello!',
  body: 'This is a test notification',
  payload: 'some_data',
);

3. Schedule Weekly Notification #

EasyNotify.scheduleWeekly(
  id: 1,
  day: DateTime.monday,
  hour: 22,
  minute: 0,
  title: 'Workout Time!',
  body: 'Let\'s keep the streak πŸ’ͺ',
);

4. Schedule Batch Notifications #

Perfect for scheduling notifications on multiple days at multiple times:

EasyNotify.scheduleBatch([
  ScheduleModel(
    days: [DateTime.monday, DateTime.wednesday, DateTime.friday],
    times: [
      TimeOfDay(hour: 10, minute: 0),
      TimeOfDay(hour: 18, minute: 0),
    ],
    title: 'Reminder',
    body: 'Time to check in!',
  ),
]);

5. Topic Management #

// Subscribe to topics
EasyNotify.subscribe('all_users');
EasyNotify.subscribeMultiple(['sports', 'offers']);

// Unsubscribe
EasyNotify.unsubscribe('premium_users');

// User type helper (automatically manages premium/free topics)
EasyNotify.setUserType(UserType.premium);

6. Get FCM Token #

String? token = await EasyNotify.getToken();
print('FCM Token: $token');

7. Listen to Events #

// Foreground messages
EasyNotify.onMessage.listen((message) {
  print('Received: ${message.notification?.title}');
});

// Notification taps
EasyNotify.onTap.listen((response) {
  print('Tapped: ${response.payload}');
});

// FCM notification opened
EasyNotify.onMessageOpened.listen((message) {
  print('Opened: ${message.data}');
});

🌍 Timezone Handling #

EasyNotify automatically handles timezones so your notifications show at the correct local time for each user.

How it works: #

  1. Device Timezone Detection: Automatically detects the user's timezone using flutter_timezone
  2. Timezone Database: Initializes the full timezone database with timezone package
  3. Smart Scheduling: All scheduled notifications use zonedSchedule with the user's local timezone

Example Scenario: #

You schedule a notification for 10:00 PM using EasyNotify.scheduleWeekly():

EasyNotify.scheduleWeekly(
  id: 1,
  day: DateTime.monday,
  hour: 22,  // 10:00 PM
  minute: 0,
  title: 'Evening Reminder',
  body: 'Time to check in!',
);

Result:

  • πŸ‡¬πŸ‡§ UK user sees it at 10:00 PM GMT (their local time)
  • πŸ‡΅πŸ‡° Pakistan user sees it at 10:00 PM PKT (their local time)
  • πŸ‡ΊπŸ‡Έ USA user sees it at 10:00 PM EST (their local time)

Each user receives the notification at 10 PM in their own timezone!

Firebase Console Scheduled Campaigns: #

When using Firebase Console to schedule campaigns:

  1. Important: Select "Recipient's local time zone" option when scheduling
  2. EasyNotify ensures the device timezone is correctly initialized
  3. Firebase uses this timezone information to deliver at the correct local time

Firebase Console Steps:

  1. Go to Firebase Console β†’ Cloud Messaging β†’ New Campaign
  2. Compose your notification
  3. Under "Scheduling", select "Recipient's local time zone" βœ…
  4. Set your desired time (e.g., 10:00 PM)
  5. All users receive it at 10:00 PM in their local timezone

Without "Recipient's local time zone":

  • If you schedule for 10:00 PM UTC
  • UK user (GMT) receives at 10:00 PM βœ…
  • Pakistan user (PKT = UTC+5) receives at 3:00 AM ❌
  • Not what you want!

Summary: #

Notification Type Timezone Handling User Experience
App Scheduled (scheduleWeekly, scheduleBatch) βœ… Automatic - uses device timezone Each user gets notification at specified local time
Firebase Console (with "Recipient's local time zone") βœ… Automatic - Firebase uses device timezone Each user gets notification at specified local time
Firebase Console (without timezone option) ❌ Uses UTC All users get notification at same UTC time (different local times)
Immediate (show()) N/A - shows immediately Shows immediately when received

Technical Details: #

EasyNotify's TimezoneService:

  • Calls tz.initializeTimeZones() to load timezone database
  • Gets device timezone with FlutterTimezone.getLocalTimezone()
  • Sets tz.setLocalLocation() for accurate scheduling
  • All scheduleWeekly and scheduleBatch calls use zonedSchedule with local timezone

πŸ“± Platform Setup #

Android #

  1. Add to android/app/build.gradle:
android {
    defaultConfig {
        minSdkVersion 21  // Required for notifications
    }
}
  1. Add to AndroidManifest.xml:
<manifest>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
    
    <application>
        <receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
        <receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

iOS #

  1. Add to ios/Runner/Info.plist:
<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
    <string>remote-notification</string>
</array>
  1. Enable capabilities in Xcode:
    • Push Notifications
    • Background Modes (Remote notifications)

🎯 Complete API Reference #

Initialization #

EasyNotify.init({
  String androidIcon,
  bool requestPermissionOnInit,
  Function(NotificationResponse)? onNotificationTap,
  Function(RemoteMessage)? onMessageOpened,
})

Show Notifications #

EasyNotify.show({required String title, required String body, String? payload, int? id})

Scheduling #

EasyNotify.scheduleWeekly({required int id, required int day, required int hour, required int minute, required String title, required String body, String? payload})
EasyNotify.scheduleBatch(List<ScheduleModel> schedules)
EasyNotify.scheduleOnce({required int id, required DateTime scheduledDate, required String title, required String body, String? payload})

Topics #

EasyNotify.subscribe(String topic)
EasyNotify.unsubscribe(String topic)
EasyNotify.subscribeMultiple(List<String> topics)
EasyNotify.unsubscribeMultiple(List<String> topics)
EasyNotify.setUserType(UserType userType)
EasyNotify.updateTopicsForUser({required bool isPremium})

Token #

EasyNotify.getToken() β†’ Future<String?>
EasyNotify.deleteToken() β†’ Future<void>

Cancel #

EasyNotify.cancel(int id)
EasyNotify.cancelAll()

Streams #

EasyNotify.onMessage β†’ Stream<RemoteMessage>
EasyNotify.onTap β†’ Stream<NotificationResponse>
EasyNotify.onMessageOpened β†’ Stream<RemoteMessage>

Utility #

EasyNotify.getPendingNotifications() β†’ Future<List<PendingNotificationRequest>>
EasyNotify.isInitialized β†’ bool

πŸ“š Models #

ScheduleModel #

ScheduleModel({
  required List<int> days,        // 1=Monday, 7=Sunday
  required List<TimeOfDay> times,
  String? title,
  String? body,
  String? payload,
})

UserType #

enum UserType {
  free,
  premium,
}

πŸ“š Example App #

Check out the example directory for a complete working app demonstrating all features.

πŸ“– Additional Documentation #

  • Quick Start Guide - Get started in 5 minutes
  • Timezone Guide - Complete timezone handling explanation
  • Platform Setup Guide - Detailed Android/iOS configuration
  • Architecture Documentation - Internal architecture and design
  • Import Guide - Understanding exports and dependencies

❓ FAQ #

Q: When I schedule a notification for 10 PM, do all users get it at their local 10 PM? #

A: Yes! That's exactly how EasyNotify works.

For app-scheduled notifications (scheduleWeekly, scheduleBatch):

  • Automatically uses each user's device timezone
  • UK user gets it at 10 PM GMT
  • Pakistan user gets it at 10 PM PKT
  • USA user gets it at 10 PM EST

For Firebase Console campaigns:

  • Select "Recipient's local time zone" when scheduling
  • EasyNotify ensures the device timezone is correctly reported
  • Each user receives at their local 10 PM

See the Timezone Guide for complete details.

Q: Do I need to add firebase_messaging or flutter_local_notifications to my pubspec.yaml? #

A: No! EasyNotify exports all the types you need. Just add:

dependencies:
  easy_notify: ^1.0.0
  firebase_core: ^2.24.2

See the Import Guide for details.

Q: How do I test notifications? #

A: Multiple ways:

  1. Immediate notification: EasyNotify.show(title: 'Test', body: 'Testing')
  2. Near-future scheduled: Schedule for 2 minutes from now
  3. Firebase Console: Use "Send test message" with your FCM token
  4. Check pending: await EasyNotify.getPendingNotifications()

See the example app for a complete testing interface.

Q: Do notifications work when the app is closed? #

A: Yes!

  • Scheduled local notifications fire even when app is closed
  • FCM background messages are handled automatically
  • EasyNotify sets up the background handler for you

Q: What about iOS permissions? #

A: Handled automatically! When you call EasyNotify.init(requestPermissionOnInit: true), it requests all necessary permissions on iOS. See Platform Setup Guide for details.


🀝 Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.


πŸ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ’‘ Why EasyNotify? #

Other notification packages require complex setup with multiple files, manual timezone handling, and separate FCM/local notification management. EasyNotify wraps everything into one simple, opinionated API that just works.

Before EasyNotify:

  • 50+ lines of boilerplate code
  • Manual timezone calculations
  • Separate FCM and local notification setup
  • Complex background handler configuration

With EasyNotify:

  • 3-5 lines of code
  • Automatic timezone handling
  • Unified API for all notification types
  • Built-in background handling

Made with ❀️ for the Flutter community

0
likes
0
points
81
downloads

Documentation

Documentation

Publisher

unverified uploader

Weekly Downloads

The easiest way to handle Firebase Cloud Messaging + Local Notifications + Timezone-aware scheduling in Flutter (Android & iOS)

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

firebase_messaging, flutter, flutter_local_notifications, flutter_timezone, timezone

More

Packages that depend on firebase_easy_notify