Swift Notifications

One API. Three Platforms. Zero Native Setup.

A simple Flutter plugin for rich push and local notifications on Android, iOS, and macOS. No native code required!

✨ Features

  • One API - Same code works on Android, iOS, and macOS
  • Rich Notifications - Images and action buttons
  • Zero Setup - No native code, no configuration files
  • Firebase Ready - Automatic Firebase integration
  • Auto Navigation - Route to screens from notifications
  • Works Everywhere - Foreground, background, and when app is closed

📦 Installation

Add this to your pubspec.yaml:

dependencies:
  swift_notifications: ^1.0.1

Then run:

flutter pub get

🚀 Quick Start

Step 1: Initialize

import 'package:swift_notifications/swift_notifications.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  final notifications = SwiftNotifications();
  await notifications.initialize();
  await notifications.requestPermission();
  
  runApp(MyApp());
}

Step 2: Show a Notification

// Simple notification
await notifications.showSimpleNotification(
  id: '1',
  title: 'Hello!',
  body: 'This is a notification',
);

// Notification with image
await notifications.showImageNotification(
  id: '2',
  title: 'New Photo',
  body: 'Check out this image!',
  imageUrl: 'https://example.com/image.jpg',
);

// Notification with buttons
await notifications.showNotification(
  NotificationRequest(
    id: '3',
    title: 'New Message',
    body: 'You have a new message',
    buttonsEnabled: true,
    actions: [
      NotificationAction(id: 'reply', title: 'Reply'),
      NotificationAction(id: 'delete', title: 'Delete'),
    ],
  ),
);

Step 3: Handle Notification Taps

notifications.onNotificationResponse.listen((response) {
  print('Notification tapped: ${response.notificationId}');
  print('Action: ${response.actionId}');
  print('Payload: ${response.payload}');
  
  // Navigate to a screen
  Navigator.pushNamed(context, '/details');
});

That's it! 🎉

📱 Platform Support

Feature Android iOS macOS
Basic Notifications
Images
Action Buttons
Firebase Push
Auto Navigation

🔥 Firebase Setup (Optional)

For remote push notifications:

1. Add Firebase Config Files

Android: Add google-services.json to android/app/
iOS: Add GoogleService-Info.plist to ios/Runner/

2. Enable Google Services (Android)

In android/app/build.gradle.kts:

plugins {
    id("com.google.gms.google-services")
}

In android/settings.gradle.kts:

plugins {
    id("com.google.gms.google-services") version "4.4.0" apply false
}

3. Send Notification from Firebase Console

  1. Go to Firebase Console → Cloud Messaging
  2. Click "Send test message"
  3. Paste your FCM token (get it with await notifications.getFCMToken())
  4. Important: Use only "Custom data" section (don't fill title/text fields)
  5. Add these fields:
id: notification_123
title: New Message
body: You have a new message
image: https://example.com/image.jpg
imageEnabled: true
buttons: [{"id":"reply","title":"Reply"}]
buttonsEnabled: true

⚠️ Critical: For images to work when app is closed, use only Custom data. Don't fill "Notification title" and "Notification text" fields.

🧭 Auto Navigation

Route to screens automatically when app opens from notification:

import 'package:screen_launch_by_notfication/screen_launch_by_notfication.dart';

SwiftFlutterMaterial(
  materialApp: MaterialApp(
    routes: {
      '/': (context) => HomeScreen(),
      '/message': (context) => MessageScreen(),
    },
  ),
  onNotificationLaunch: ({required isFromNotification, required payload}) {
    if (isFromNotification && payload['type'] == 'message') {
      return SwiftRouting(
        route: '/message',
        payload: payload,
      );
    }
    return null;
  },
)

📚 API Reference

Initialize

await notifications.initialize();

Request Permission

final status = await notifications.requestPermission();

Show Simple Notification

await notifications.showSimpleNotification(
  id: 'unique_id',
  title: 'Title',
  body: 'Body text',
  payload: {'key': 'value'}, // Optional
);

Show Image Notification

await notifications.showImageNotification(
  id: 'unique_id',
  title: 'Title',
  body: 'Body text',
  imageUrl: 'https://example.com/image.jpg',
);

Show Notification with Buttons

await notifications.showNotification(
  NotificationRequest(
    id: 'unique_id',
    title: 'Title',
    body: 'Body text',
    buttonsEnabled: true,
    actions: [
      NotificationAction(id: 'action1', title: 'Action 1'),
      NotificationAction(id: 'action2', title: 'Action 2'),
    ],
  ),
);

Listen to Notification Taps

notifications.onNotificationResponse.listen((response) {
  // Handle tap or button click
});

Get FCM Token (Firebase)

final token = await notifications.getFCMToken();

Cancel Notifications

await notifications.cancelNotification('notification_id');
await notifications.cancelAllNotifications();

🎯 Intercept Notifications

Hide notifications and do something custom:

notifications.setNotificationInterceptor((event) async {
  if (event.payloadContains('no_show')) {
    // Do something without showing notification
    return NotificationInterceptionResult.hide;
  }
  return NotificationInterceptionResult.show;
});

💬 Custom Action Handlers

Show custom UI for button actions (like WhatsApp reply):

notifications.registerCustomActionHandler('reply', (response, sendResponse) {
  showDialog(
    context: context,
    builder: (context) => ReplyDialog(
      onSend: (text) => sendResponse?.call(text),
    ),
  );
});

// Listen to responses
notifications.onCustomActionResponse.listen((response) {
  print('Reply: ${response.responseData['text']}');
});

🐛 Troubleshooting

Images Not Showing in Cold State

Problem: Images don't show when app is closed.

Solution: In Firebase Console, use only Custom data. Don't fill "Notification title" and "Notification text" fields.

See FIREBASE_COLD_STATE_IMAGES.md for details.

App Not Opening on Notification Tap

Solution: Already fixed! The plugin automatically opens the app when notification is tapped.

Permission Denied

Solution: Request permission:

await notifications.requestPermission();

📖 Examples

See the example/ directory for a complete working example.

🤝 Contributing

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

📄 License

See the LICENSE file for details.


Made with ❤️ for Flutter developers