Core Methods

initialize()

PntaFlutter.initialize(String projectId, {bool autoHandleLinks, bool showSystemUI})

Initializes the plugin with configuration options.

Parameters:

  • projectId: Your PNTA project ID (format: prj_XXXXXXXXX)
  • autoHandleLinks (optional): Automatically handle link_to URLs when notifications are tapped from background/terminated state. Default: false
  • showSystemUI (optional): Show system notification banner/sound when app is in foreground. Default: false

Returns: Future<void>

Examples:

lib/main.dart
// Minimal - only required parameter
await PntaFlutter.initialize('prj_XXXXXXXXX');

// With optional parameters
await PntaFlutter.initialize(
  'prj_XXXXXXXXX',        // Your PNTA project ID
  autoHandleLinks: true,  // Optional: enable auto-handling of links
  showSystemUI: true,     // Optional: show system UI in foreground
);

requestNotificationPermission()

PntaFlutter.requestNotificationPermission()

Requests notification permission from the user.

Returns: Future<bool> - true if permission granted, false otherwise

Example:

lib/main.dart
final granted = await PntaFlutter.requestNotificationPermission();
if (granted) {
  print('Permission granted');
} else {
  print('Permission denied');
}

identify()

PntaFlutter.identify({Map<String, dynamic>? metadata})

Registers the device with your PNTA project. Should be called on every app startup after permission is granted.

Parameters:

  • metadata (optional): Device metadata as key-value pairs

Returns: Future<String?> - Device token if you need it for your backend

Examples:

lib/main.dart
// Without storing token
await PntaFlutter.identify(metadata: {
  'user_id': '123',
  'user_email': '[email protected]',
});

// With token returned
final token = await PntaFlutter.identify(metadata: {
  'user_id': '123',
  'user_email': '[email protected]',
});
if (token != null) {
  print('Device token: $token');
}

Requires notification permission to obtain the device token. Always call after requestNotificationPermission() returns true.

updateMetadata()

PntaFlutter.updateMetadata({Map<String, dynamic>? metadata})

Updates device metadata without re-registering.

Parameters:

  • metadata (optional): Updated metadata

Returns: Future<void>

Example:

lib/main.dart
await PntaFlutter.updateMetadata(metadata: {
  'last_active': DateTime.now().toIso8601String(),
});
PntaFlutter.handleLink(String link)

Manually handles a link using the plugin’s routing logic.

Parameters:

  • link: The link to handle

Returns: void

Example:

lib/main.dart
PntaFlutter.handleLink('/profile');
PntaFlutter.handleLink('https://example.com');

Properties

PntaFlutter.navigatorKey

Global navigator key for internal route navigation. Must be assigned to your MaterialApp.

Type: GlobalKey<NavigatorState>

Example:

lib/main.dart
MaterialApp(
  navigatorKey: PntaFlutter.navigatorKey,
  // ... rest of your app
)

foregroundNotifications

PntaFlutter.foregroundNotifications

Stream of notification payloads received when app is in foreground.

Type: Stream<Map<String, dynamic>>

Example:

lib/main.dart
PntaFlutter.foregroundNotifications.listen((payload) {
  print('Received: ${payload['title']}');

  // Show custom UI
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text('${payload['title']}: ${payload['body']}')),
  );
});

onNotificationTap

PntaFlutter.onNotificationTap

Stream of notification payloads when user taps a notification from background/terminated state.

Type: Stream<Map<String, dynamic>>

Example:

lib/main.dart
PntaFlutter.onNotificationTap.listen((payload) {
  print('User tapped: ${payload['title']}');
  // Track analytics, navigate to specific screen, etc.
});

The plugin handles notification links automatically based on URL format:

  • External URLs (with ://) → Opens in system browser/apps
    • Examples: https://example.com, mailto:[email protected], tel:+1234567890
    • Requires Android <queries> permissions (covered in Platform Setup)
  • Internal routes (without ://) → Navigates using Flutter’s Navigator
    • Examples: /profile, /settings, /dashboard
    • Requires navigatorKey setup (covered in Quick Start)

Best Practices

Memory Management

Always cancel stream subscriptions to avoid memory leaks:

lib/pages/my_page.dart
class _MyWidgetState extends State<MyWidget> {
  late StreamSubscription _foregroundSub;
  late StreamSubscription _tapSub;

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

    _foregroundSub = PntaFlutter.foregroundNotifications.listen((payload) {
      // Handle foreground notification
    });

    _tapSub = PntaFlutter.onNotificationTap.listen((payload) {
      // Handle notification tap
    });
  }

  @override
  void dispose() {
    _foregroundSub.cancel();
    _tapSub.cancel();
    super.dispose();
  }
}

Error Handling

Wrap API calls in try-catch blocks:

lib/main.dart
try {
  await PntaFlutter.identify(metadata: userMetadata);
} catch (e) {
  print('Failed to identify device: $e');
  // Handle error appropriately
}