payghaam_flutter includes Kotlin that talks to FCM directly. You still need a Firebase project and google-services.json, but you do not add the firebase_messaging Flutter plugin.
Firebase + google-services.json
- Create a Firebase project and add your Android app (package name =
applicationId). - Download
google-services.jsonintoandroid/app/. - Upload the matching FCM service-account JSON in the dashboard → Channels → Android · FCM.
Gradle wiring
Project-level android/build.gradle:
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.4.2'
}
}App-level android/app/build.gradle:
apply plugin: 'com.google.gms.google-services'The Payghaam plugin depends on the native Android SDK, which pulls in firebase-messaging transitively. Ensure minSdkVersion ≥ 21 and JVM target 17.
Dart (same as iOS)
final push = PayghaamPushProvider();
await Payghaam.instance.initialize(config, push: push);
await Payghaam.instance.login('user-id');
await Payghaam.instance.requestPushPermission();
await push.shareConfig(
apiBase: config.baseUrl,
apiKey: config.apiKey,
externalId: 'user-id',
);Delivery by app state
| State | Mechanism | Receipt |
|---|---|---|
| Foreground | PayghaamFirebaseMessagingService | delivered |
| Tap (background / killed) | PendingIntent → plugin | opened |
| Data message while terminated | FCM service → receipts API | delivered |
Custom notification sound
On Android 8+ a sound is a property of the notification channel and is fixed once the channel is created, so a custom sound means routing the notification to a channel that already carries it.
- Add the audio file to
android/app/src/main/res/raw/(e.g.chime.mp3). The resource name must be lowercase with no spaces. - Enter its extensionless name (
chime) in the Android sound field in the dashboard. - Payghaam mirrors that value into the FCM data payload as
ek_sound. Read it inPayghaamFirebaseMessagingService.showNotification(...)and build a per-sound channel:
val soundName = message.data["ek_sound"] // e.g. "chime"
val channelId = if (soundName.isNullOrBlank()) "payghaam_default"
else "payghaam_sound_$soundName"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
nm.getNotificationChannel(channelId) == null) {
val channel = NotificationChannel(
channelId, "Notifications", NotificationManager.IMPORTANCE_HIGH,
)
if (!soundName.isNullOrBlank()) {
val uri = Uri.parse("android.resource://$packageName/raw/$soundName")
val attrs = AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()
channel.setSound(uri, attrs)
}
nm.createNotificationChannel(channel)
}On Android 7 and below there are no channels — call builder.setSound(uri) on the Notification.Builder instead. See Rich notifications for the cross-platform overview.
Warning
chime → chime_v2) so a fresh channel is made.Tip
POST_NOTIFICATIONS permission —requestPushPermission() triggers the system prompt.Troubleshooting
- Build fails with AGP/Kotlin/JVM errors. The native Android SDK requires JVM target 17 (see Gradle wiring above) — mismatched Kotlin, Android Gradle Plugin, or Java toolchain versions on an older project setup are the usual cause. Align
compileOptions/kotlinOptionsto Java 17 and update AGP/Kotlin if needed. - FCM registration fails or push never arrives. The package name inside
google-services.jsonmust match yourapplicationIdexactly — a mismatch (including flavor suffixes) fails token registration silently. Re-download the file from Firebase if you changed the application id.
