ابرووا
شروع رایگان
☰ فهرست مستندات · Flutter
به‌زودی. Abrova Push به‌زودی فعال می‌شود. این صفحه توضیح می‌دهد چطور کار خواهد کرد؛ هنوز قابل استفاده نیست.
این صفحه هنوز ترجمه نشده — نسخه‌ی انگلیسی نمایش داده می‌شود. English

Flutter SDK

Cross-platform Flutter SDK for real-time push notifications, in-app messages, inbox, A/B testing, and analytics. No Firebase dependency.

Flutter 0.1.20Dart 3.0+Flutter 3.3+Android 5.0+iOS 13+به‌روزرسانی: ۵ آبان ۱۴۰۵
Push Notifications

Real-time delivery on Android & iOS via persistent connection

In-App Messages

Modal, banner, fullscreen layouts triggered by events

Inbox

Persistent message center with read / archive / unread count

A/B Testing

Experiment variant assignment with delivery tracking

Topics & Silent Messages

Broadcast to interest groups or deliver data-only payloads

Auto-reconnect

Exponential backoff handles flaky networks

Notification Tap Handling

Cold-start initial message + foreground tap callback

No Google/Firebase Required

Full control over your push infrastructure; optional FCM bridge on Android

Installation#

AbrovaPush installs from Abrova Center in two steps.

  1. Add the package to pubspec.yaml, pointing at Abrova Center:
yaml
dependencies:
  abrova_push:
    hosted: https://center.abrova.ir/api/packages/abrova/pub
    version: ^0.1.20
  1. Fetch the package:
bash
flutter pub get

Android repository

The plugin uses the native Android SDK. Add the Abrova Center repository in android/build.gradle (or android/settings.gradle, wherever your project lists repositories):

groovy
allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url "https://center.abrova.ir/api/packages/abrova/maven" }
    }
}

iOS native SDK

The plugin uses the native iOS SDK. Add it inside the app target in ios/Podfile, then run pod install in ios/:

ruby
pod 'AbrovaPushSDK', :git => 'https://github.com/Abrova-co/abrova-push-ios-sdk.git', :tag => '0.1.16'

Android Manifest

Add to android/app/src/main/AndroidManifest.xml:

xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

iOS Capabilities

In Xcode → Signing & Capabilities enable:

  • Push Notifications
  • Background Modes → Remote notifications

Quick Start#

Initialize AbrovaPush before runApp:

dart
import 'package:flutter/material.dart';
import 'package:abrova_push/abrova_push.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await AbrovaPush.init(AbrovaPushConfig(
    apiKey: 'ab_live_your_api_key',
  ));

  runApp(const MyApp());
}

Register and Receive Messages#

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

  // Listen for messages
  AbrovaPush.onMessage((message) {
    // message.title, message.body, message.data
  });

  // Connection status
  AbrovaPush.onConnectionState((connected) {
    // true / false
  });

  // Register the device
  AbrovaPush.register(userId: 'user_123');
}

Notification Tap Handling#

When the app cold-starts from a notification tap, fetch the initial message before showing UI:

dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await AbrovaPush.init(config);

  final initialMessage = await AbrovaPush.getInitialMessage();
  if (initialMessage != null) {
    runApp(MyApp(initialRoute: routeFor(initialMessage)));
  } else {
    runApp(const MyApp());
  }
}

For taps that happen while the app is running, listen via callback:

dart
AbrovaPush.onNotificationTapped((AbrovaPushMessage message) {
  // Navigate based on message.data
});

User Identification#

dart
// Set user ID after login
await AbrovaPush.setUserId('user_123');

// Clear user ID after logout
await AbrovaPush.clearUserId();

// Register with user ID + metadata in one call
await AbrovaPush.register(
  userId: 'user_123',
  metadata: {'appVersion': '1.0.0', 'language': 'en'},
);

Topics#

dart
await AbrovaPush.subscribeTopic('news');
await AbrovaPush.subscribeTopic('promotions');

await AbrovaPush.unsubscribeTopic('promotions');

In-App Messages#

Trigger in-app messages on app open or custom events. To display them, wrap your app in AbrovaPushInAppOverlay; the native SDKs do not render in-app UI for Flutter (see In-App Messages):

dart
// On app open
await AbrovaPush.triggerInAppOnAppOpen();

// On custom event with properties
await AbrovaPush.triggerInAppEvent('purchase_complete', properties: {
  'amount': 29.99,
});

// Button taps on overlay-rendered messages arrive in the overlay's onButtonTap
MaterialApp(
  builder: (context, child) => AbrovaPushInAppOverlay(
    onButtonTap: (context, message, button) {
      // User tapped an action button
    },
    child: child ?? const SizedBox.shrink(),
  ),
);

AbrovaPushInAppOverlay listens through AbrovaPush.onInAppMessageReady, which holds a single callback; setting your own onInAppMessageReady replaces the overlay's listener.

Inbox#

Inbox messages are stored server-side (sent from Abrova Console or the Inbox API, separately from pushes) so users can revisit them:

dart
// Fetch inbox messages
final response = await AbrovaPush.getInboxMessages(
  status: InboxMessageStatus.unread,
  limit: 50,
);

// Mark as read
await AbrovaPush.markInboxMessageAsRead(messageId);

// Archive
await AbrovaPush.archiveInboxMessage(messageId);

// Unread count for badges
final count = await AbrovaPush.getInboxUnreadCount();

// Listen for new inbox messages
AbrovaPush.onInboxMessage((message) {
  // message.content.title, message.content.body
});

A/B Testing#

dart
// Get active tests
final tests = await AbrovaPush.getActiveABTests();

// Get the assigned variant for a test
final variant = await AbrovaPush.getABTestVariant('test_id');
if (variant != null) {
  // variant.variantName, variant.content
}

// Track events
await AbrovaPush.trackABTestImpression('test_id', 'variant_id');
await AbrovaPush.trackABTestClicked('test_id', 'variant_id');

// Listen for new variant assignments
AbrovaPush.onABTestVariantAssigned((variant) {
  // Newly assigned to a variant
});

Analytics#

Forward SDK events to your analytics service:

dart
AbrovaPush.setAnalyticsHandler((event, properties) {
  // Example: forward to Firebase Analytics
  FirebaseAnalytics.instance.logEvent(
    name: 'abrova_push_${event.name}',
    parameters: properties?.map((k, v) => MapEntry(k, v.toString())),
  );
});

Log Levels#

dart
import 'package:flutter/foundation.dart';

if (kReleaseMode) {
  await AbrovaPush.setLogLevel(AbrovaPushLogLevel.error);
} else {
  await AbrovaPush.setLogLevel(AbrovaPushLogLevel.debug);
}

Available levels: none, error, warning, info, debug, verbose.

Configuration Options#

dart
await AbrovaPush.init(AbrovaPushConfig(
  apiKey: 'ab_live_your_api_key',
  notificationIcon: 'ic_notification',
  usePushKit: false,
  showServiceNotification: true,
  showNotificationInForeground: true,
));
OptionTypeRequiredDescription
apiKeyStringYesYour project API Key from the dashboard
notificationIconString?NoAndroid notification icon resource name
usePushKitboolNoEnable iOS PushKit VoIP for calling apps (default: true)
showServiceNotificationboolNoShow Android foreground-service notification (default: true)
showNotificationInForegroundboolNoShow notifications when the app is in foreground (default: true)
autoConnectboolNoAuto-connect when the app enters the foreground (default: true)
autoRefreshboolNoRefresh a previously registered device in the background on launch (default: true)
appGroupString?NoiOS only. App Group shared with a Notification Service Extension, for delivery confirmation (see iOS Delivery Confirmation below)
Auto-configured Connection.

Connection configuration is fetched from the server using your API key. No manual setup is needed.

VoIP Calls (Optional)#

For apps with calling features, add the companion VoIP plugin for native incoming-call UI:

yaml
dependencies:
  abrova_push:
    hosted: https://center.abrova.ir/api/packages/abrova/pub
    version: ^0.1.20
  abrova_push_voip:  # Optional - for calling apps
    hosted: https://center.abrova.ir/api/packages/abrova/pub
    version: ^0.1.1
dart
await AbrovaPushVoIP.init(
  config: AbrovaPushVoIPConfig(appName: 'MyApp'),
  onCallAccepted: (callData) => navigateToCallScreen(callData),
  onCallDeclined: (callData) => notifyCallDeclined(callData.callId),
);

// Register VoIP after AbrovaPush has issued a deviceId
final deviceId = await AbrovaPush.getDeviceId();
await AbrovaPushVoIP.setApiKey(apiKey: 'ab_live_your_api_key', deviceId: deviceId); // deviceId is optional

Trigger an incoming call from the backend with type: "voip_call":

json
{
  "title": "Incoming Call",
  "body": "John Doe is calling",
  "data": {
    "type": "voip_call",
    "callerName": "John Doe",
    "callerId": "user_456",
    "callType": "video"
  }
}

iOS Delivery Confirmation (Optional)#

Optional, iOS only. Android confirms delivery on its own — nothing to do there. On iOS, APNs only reports that Apple accepted a notification, so without this step iOS devices report sent and never delivered.

Confirming delivery on iOS requires a Notification Service Extension, which is a native Xcode target. Follow the full walkthrough in the iOS SDK guide — adding the target, enabling an App Group on both targets, and adding the SDK to the extension target.

From Flutter, the only change is passing the same App Group to the config:

dart
await AbrovaPush.init(AbrovaPushConfig(
  apiKey: 'ab_live_your_api_key',
  // iOS only. Must match the App Group enabled on BOTH your Runner target and
  // the Notification Service Extension target.
  appGroup: 'group.com.yourcompany.yourapp',
));

appGroup is ignored on Android, so it is safe to pass unconditionally.

The App Group string must match exactly.

It appears in four places: both targets' capabilities, your extension's Swift code, and AbrovaPushConfig. A mismatch fails silently — the extension runs, finds no device identity, and reports nothing.

API Reference#

AbrovaPush — Initialization & Lifecycle

OptionTypeRequiredDescription
init(config)--Initialize the SDK with an AbrovaPushConfig
register(userId?, metadata?)--Register the device with the Abrova backend
unregister()--Unregister the device
isConnected()--Check whether the real-time connection is open
getDeviceId()--Get the current device identifier

Callbacks

OptionTypeRequiredDescription
onMessage(callback)--Called when a push message is received
onConnectionState(callback)--Connection open / closed state changes
onRegistered(callback)--Device registration completed
onNotificationTapped(callback)--User tapped a notification while app is running
onError(callback)--String error message
onDetailedError(callback)--Structured AbrovaPushError with code + message
onReconnecting(callback)--Reconnection attempt state
onNetworkState(callback)--Network availability change
onAppState(callback)--App foreground / background change

User & Topics

OptionTypeRequiredDescription
setUserId(id)--Set the current user identifier
clearUserId()--Clear the user identifier
subscribeTopic(topic)--Subscribe to a topic
unsubscribeTopic(topic)--Unsubscribe from a topic

Inbox

OptionTypeRequiredDescription
getInboxMessages(status?, limit?)--Fetch a page of inbox messages
markInboxMessageAsRead(id)--Mark an inbox message as read
archiveInboxMessage(id)--Archive an inbox message
getInboxUnreadCount()--Get the unread count for badges
onInboxMessage(callback)--Listen for new inbox messages

In-App Messages

OptionTypeRequiredDescription
triggerInAppOnAppOpen()--Trigger any in-app message registered for app-open
triggerInAppEvent(event, properties?)--Trigger in-app messages registered for a custom event
onInAppMessageReady(callback)--An in-app message matched a trigger (used by AbrovaPushInAppOverlay)
onInAppButtonClick(callback)--Button tap on a natively rendered message; overlay taps go to AbrovaPushInAppOverlay.onButtonTap

A/B Testing

OptionTypeRequiredDescription
getActiveABTests()--Get active A/B tests
getABTestVariant(testId)--Get the assigned variant for a test
trackABTestImpression(testId, variantId)--Track an impression
trackABTestClicked(testId, variantId)--Track a click conversion
onABTestVariantAssigned(callback)--Listen for new variant assignments

Best Practices#

Initialize Before runApp

Call WidgetsFlutterBinding.ensureInitialized() then await AbrovaPush.init() before runApp so callbacks are ready

Check Initial Message on Cold Start

Always await getInitialMessage() before showing your first screen so deep-link taps land on the right route

Set User ID After Login

Call setUserId() once authentication completes so notifications target the right account across devices

Use Topics for Broad Audiences

Topics suit large audiences; use for newsletters, sports scores, news categories

Use Segments for Targeted Sends

Segments evaluate user metadata server-side — better for product launches and re-engagement

Forward Analytics

Wire setAnalyticsHandler to your analytics provider so SDK events (messages, connection, in-app, inbox, A/B tests) show up next to your other product metrics

این صفحه مفید بود؟
گزارش مشکل