Cihazın durumuna bağlı olarak, gelen iletiler farklı şekilde işlenir. Bu senaryoları ve FCM'yi kendi uygulamanıza nasıl entegre edeceğinizi anlamak için öncelikle bir cihazın bulunabileceği çeşitli durumları belirlemeniz önemlidir:
Eyalet | Açıklama |
---|---|
Ön plan | Uygulama açık, görünür ve kullanımda olduğunda. |
Genel bilgi | Uygulama açık ancak arka planda (küçültülmüş) olduğunda. Bu durum genellikle kullanıcı cihazdaki "ana sayfa" düğmesine bastığında, uygulama değiştiriciyi kullanarak başka bir uygulamaya geçtiğinde veya uygulamayı farklı bir sekmede (web) açtığında meydana gelir. |
Sonlandırıldı | Cihaz kilitli veya uygulama çalışmıyorken. |
Uygulamanın FCM aracılığıyla mesaj yüklerini alabilmesi için karşılanması gereken birkaç ön koşul vardır:
- Başvuru, FCM'ye kayıt için en az bir kez açılmış olmalıdır.
- iOS'te, kullanıcı uygulamayı uygulama değiştiriciden hızlıca kaydırırsa arka plan mesajlarının tekrar çalışmaya başlaması için uygulamanın manuel olarak yeniden açılması gerekir.
- Android'de, kullanıcı cihaz ayarlarından uygulamadan zorla çıkarsa mesajların çalışmaya başlaması için uygulama manuel olarak yeniden açılmalıdır.
- Web'de, web push sertifikanızla birlikte bir jeton (
getToken()
kullanarak) istemiş olmanız gerekir.
Mesaj almak için izin isteme
iOS, macOS, web ve Android 13'te (veya daha yeni sürümlerde) FCM yüklerinin cihazınızda alınabilmesi için önce kullanıcının iznini almanız gerekir.
firebase_messaging
paketi, requestPermission
yöntemiyle izin istemek için basit bir API sunar.
Bu API, talep etmek istediğiniz izin türlerini tanımlayan çeşitli adlandırılmış bağımsız değişkenleri kabul eder (örneğin, bildirim yüklerini içeren mesajların Siri aracılığıyla bir ses tetiklemesi veya mesajları sesli okuması gibi). Varsayılan olarak bu yöntem, makul varsayılan izinler ister. Referans API, her iznin neyle ilgili olduğuyla ilgili tüm belgeleri sunar.
Başlamak için uygulamanızdaki yöntemi çağırın (iOS'te yerel bir kalıcı mod gösterilir, web'de tarayıcının yerel API akışı tetiklenir):
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
print('User granted permission: ${settings.authorizationStatus}');
İstekten döndürülen NotificationSettings
nesnesinin authorizationStatus
özelliği, kullanıcının genel kararını belirlemek için kullanılabilir:
authorized
: Kullanıcı izin verdi.denied
: Kullanıcı izni reddetti.notDetermined
: Kullanıcı, izin verip vermeyeceğini henüz seçmedi.provisional
: Kullanıcı geçici izin verdi
NotificationSettings
alanındaki diğer mülkler, belirli bir iznin mevcut cihazda etkin, devre dışı veya desteklenmiyor olup olmadığını döndürür.
İzin verildikten ve farklı cihaz durumu türleri anlaşıldıktan sonra uygulamanız artık gelen FCM yüklerini işlemeye başlayabilir.
Mesaj işleme
Uygulamanızın mevcut durumuna bağlı olarak, farklı mesaj türlerinden gelen yüklerinin işlenmesi için farklı uygulamalar gerekir:
Ön plan mesajları
Uygulamanız ön plandayken mesajları işlemek için onMessage
akışını dinleyin.
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message whilst in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
});
Akış; yük hakkında nerede olduğu, benzersiz kimlik, gönderilme zamanı, bildirim içerip içermediği gibi yük hakkında çeşitli bilgileri ayrıntılı olarak gösteren bir RemoteMessage
içerir. Mesaj, uygulamanız ön plandayken alındığı için Flutter uygulamanızın durum ve bağlamına doğrudan erişebilirsiniz.
Ön plan ve Bildirim mesajları
Uygulama ön plandayken gelen bildirim mesajları, hem Android'de hem de iOS'te varsayılan olarak görünür bir bildirim görüntülemez. Ancak, bu davranışı geçersiz kılmak mümkündür:
- Android'de "Yüksek Öncelikli" bildirim kanalı oluşturmalısınız.
- iOS'te, uygulamanın sunu seçeneklerini güncelleyebilirsiniz.
Arka plan mesajları
Arka plan mesajlarının işlenme süreci yerel platformlarda (Android ve Apple) ve web tabanlı platformlarda farklıdır.
Apple platformları ve Android
Bir onBackgroundMessage
işleyicisi kaydederek arka plan mesajlarını işleyin. Mesajlar alındığında, bir yalıtım oluşturulur (yalnızca Android, iOS/macOS ayrı bir yalıtım gerektirmez). Bu sayede, uygulamanız çalışmıyorken bile mesajları ele alabilirsiniz.
Arka plan mesajı işleyicinizle ilgili olarak aklınızda bulundurmanız gereken birkaç şey vardır:
- Anonim bir işlev olmamalıdır.
- Üst düzey bir işlev olmalıdır (ör. başlatma gerektiren bir sınıf yöntemi olmamalıdır).
- Flutter 3.3.0 veya sonraki bir sürümünü kullanırken, mesaj işleyicide işlev bildiriminin hemen üzerinde
@pragma('vm:entry-point')
ek açıklaması yer almalıdır (aksi takdirde serbest bırakma modu için ağaç sallama sırasında kaldırılabilir).
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
}
void main() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
İşleyici, uygulama bağlamı dışında kendi izolasyonunda çalıştığından uygulama durumunu güncellemek veya kullanıcı arayüzünü etkileyen mantığı yürütmek mümkün değildir. Bununla birlikte, HTTP istekleri gibi mantıksal işlemleri gerçekleştirebilir, G/Ç işlemleri (ör. yerel depolama alanını güncelleme) gerçekleştirebilir, diğer eklentilerle iletişim kurabilirsiniz.
Ayrıca mantığınızı en kısa sürede tamamlamanız önerilir. Uzun ve yoğun görevlerin çalıştırılması cihaz performansını etkiler ve işletim sisteminin işlemi sonlandırmasına neden olabilir. Görevler 30 saniyeden daha uzun sürerse cihaz işlemi otomatik olarak sonlandırabilir.
Web
Web'de, arka planda çalışan bir JavaScript Hizmet Çalışanı yazın. Arka plandaki mesajları işlemek için Service Worker'ı kullanın.
Başlamak için web
dizininizde yeni bir dosya oluşturun ve bu dosyayı firebase-messaging-sw.js
olarak adlandırın:
importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js");
firebase.initializeApp({
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
});
const messaging = firebase.messaging();
// Optional:
messaging.onBackgroundMessage((message) => {
console.log("onBackgroundMessage", message);
});
Dosya hem uygulama hem de mesajlaşma SDK'larını içe aktarmalı, Firebase'i başlatmalı ve messaging
değişkenini göstermelidir.
Ardından, çalışanın kaydedilmesi gerekir. main.dart.js
dosyası yüklendikten sonra giriş dosyasında çalışanınızı kaydedin:
<html>
<body>
...
<script src="main.dart.js" type="application/javascript"></script>
<script>
if ('serviceWorker' in navigator) {
// Service workers are supported. Use them.
window.addEventListener('load', function () {
// ADD THIS LINE
navigator.serviceWorker.register('/firebase-messaging-sw.js');
// Wait for registration to finish before dropping the <script> tag.
// Otherwise, the browser will load the script multiple times,
// potentially different versions.
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
// ...
});
}
</script>
Ardından Flutter uygulamanızı yeniden başlatın. Çalışan kaydedilecek ve arka plan mesajları bu dosya üzerinden işlenecek.
Etkileşimi Yönetme
Bildirimler görünür bir işaret olduğundan, kullanıcıların onlarla etkileşim kurması (basarak) yaygındır. Hem Android'de hem de iOS'te varsayılan davranış, uygulamayı açmaktır. Uygulama sonlandırılırsa başlatılır, arka plandaysa ön plana getirilir.
Bir bildirimin içeriğine bağlı olarak, kullanıcının uygulama açıldığında etkileşimini yönetmek isteyebilirsiniz. Örneğin, bildirim aracılığıyla yeni bir sohbet mesajı gönderilirse ve kullanıcı bu mesaja basarsa uygulama açıldığında ilgili ileti dizisini açmak isteyebilirsiniz.
firebase-messaging
paketi, bu etkileşimi yönetmek için iki yol sunar:
getInitialMessage()
: Uygulama sonlandırılmış bir durumda açılırsaRemoteMessage
içeren birFuture
döndürülür. Kullanıldıktan sonraRemoteMessage
kaldırılır.onMessageOpenedApp
: Uygulama arka plan durumundan açıldığındaRemoteMessage
mesajı yayınlayan birStream
.
Kullanıcılarınıza sorunsuz bir kullanıcı deneyimi sunmak için her iki senaryonun da ele alınması önerilir. Aşağıdaki kod örneğinde bunun nasıl elde edilebileceği özetlenmiştir:
class Application extends StatefulWidget {
@override
State<StatefulWidget> createState() => _Application();
}
class _Application extends State<Application> {
// It is assumed that all messages contain a data field with the key 'type'
Future<void> setupInteractedMessage() async {
// Get any messages which caused the application to open from
// a terminated state.
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
// If the message also contains a data property with a "type" of "chat",
// navigate to a chat screen
if (initialMessage != null) {
_handleMessage(initialMessage);
}
// Also handle any interaction when the app is in the background via a
// Stream listener
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
}
void _handleMessage(RemoteMessage message) {
if (message.data['type'] == 'chat') {
Navigator.pushNamed(context, '/chat',
arguments: ChatArguments(message),
);
}
}
@override
void initState() {
super.initState();
// Run code required to handle interacted messages in an async function
// as initState() must not be async
setupInteractedMessage();
}
@override
Widget build(BuildContext context) {
return Text("...");
}
}
Etkileşimi nasıl ele alacağınız, uygulama kurulumunuza bağlıdır. Yukarıdaki örnekte, StatefulWidget kullanan temel bir açıklama gösterilmektedir.
İletileri Yerelleştirme
Yerelleştirilmiş dizeleri iki farklı şekilde gönderebilirsiniz:
- Sunucunuzda her kullanıcı için tercih edilen dili depolayın ve her dil için özelleştirilmiş bildirimler gönderin
- Yerelleştirilmiş dizeleri uygulamanıza yerleştirin ve işletim sisteminin yerel yerel ayarlarından yararlanın
İkinci yöntemin nasıl kullanılacağı aşağıda açıklanmıştır:
Android
resources/values/strings.xml
dilinde varsayılan dildeki mesajlarınızı belirtin:<string name="notification_title">Hello world</string> <string name="notification_message">This is a message</string>
values-language
dizininde çevrilmiş iletileri belirtin. Örneğin,resources/values-fr/strings.xml
dilinde Fransızca mesajları belirtin:<string name="notification_title">Bonjour le monde</string> <string name="notification_message">C'est un message</string>
Sunucu yükünde, yerelleştirilmiş mesajınız için
title
,message
vebody
anahtarlarını kullanmak yerinetitle_loc_key
vebody_loc_key
değerlerini kullanın ve bunları, görüntülemek istediğiniz mesajınname
özelliğine ayarlayın.Mesaj yükü aşağıdaki gibi görünür:
{ "data": { "title_loc_key": "notification_title", "body_loc_key": "notification_message" } }
iOS
Base.lproj/Localizable.strings
dilinde varsayılan dildeki mesajlarınızı belirtin:"NOTIFICATION_TITLE" = "Hello World"; "NOTIFICATION_MESSAGE" = "This is a message";
language.lproj
dizininde çevrilmiş iletileri belirtin. Örneğin,fr.lproj/Localizable.strings
dilinde Fransızca mesajları belirtin:"NOTIFICATION_TITLE" = "Bonjour le monde"; "NOTIFICATION_MESSAGE" = "C'est un message";
Mesaj yükü aşağıdaki gibi görünür:
{ "data": { "title_loc_key": "NOTIFICATION_TITLE", "body_loc_key": "NOTIFICATION_MESSAGE" } }
Mesaj teslimi verilerini dışa aktarmayı etkinleştir
Mesaj verilerinizi daha ayrıntılı analiz için BigQuery'ye aktarabilirsiniz. BigQuery, verileri BigQuery SQL kullanarak analiz etmenize, başka bir bulut sağlayıcıya aktarmanıza veya özel ML modellerinizde kullanmak istediğiniz verileri kullanmanıza olanak tanır. BigQuery'ye aktarma işlemi, mesaj türüne veya mesajın API ya da Notifications oluşturucu aracılığıyla gönderilmesine bakılmaksızın, mesajlar için mevcut tüm verileri içerir.
Dışa aktarmayı etkinleştirmek için önce burada açıklanan adımları uygulayın, ardından şu talimatları uygulayın:
Android
Şu kodu kullanabilirsiniz:
await FirebaseMessaging.instance.setDeliveryMetricsExportToBigQuery(true);
iOS
iOS için AppDelegate.m
bölümünü aşağıdaki içerikle değiştirmeniz gerekir.
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
#import <Firebase/Firebase.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[[FIRMessaging extensionHelper] exportDeliveryMetricsToBigQueryWithMessageInfo:userInfo];
}
@end
Web
Web söz konusu olduğunda, SDK'nın v9 sürümünü kullanmak için hizmet çalışanınızı değiştirmeniz gerekir.
v9 sürümünün paket haline getirilmesi gerekir. Bu nedenle, hizmet çalışanının çalışmasını sağlamak için esbuild
gibi bir paketleyici kullanmanız gerekir.
Bunun nasıl yapılacağını öğrenmek için örnek uygulamaya bakın.
v9 SDK'sına geçiş yaptıktan sonra aşağıdaki kodu kullanabilirsiniz:
import {
experimentalSetDeliveryMetricsExportedToBigQueryEnabled,
getMessaging,
} from 'firebase/messaging/sw';
...
const messaging = getMessaging(app);
experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);
Service Worker'ınızın yeni sürümünü web
klasörüne aktarmak için yarn build
komutunu çalıştırmayı unutmayın.
iOS'teki bildirimlerde resimleri göster
Apple cihazlarda, gelen FCM Bildirimleri'nin FCM yükündeki resimleri göstermesi için ek bir bildirim hizmeti uzantısı eklemeniz ve uygulamanızı bunu kullanacak şekilde yapılandırmanız gerekir.
Firebase telefonla kimlik doğrulamayı kullanıyorsanız Firebase Auth kapsülünü Podfile'ınıza eklemeniz gerekir.
1. Adım - Bildirim hizmet uzantısı ekleyin
- Xcode'da File > New > Target... (Dosya > Yeni > Hedef...) seçeneğini tıklayın.
- Kalıcı bir seçenek, olası hedeflerin listesini sunar. Sayfayı aşağı kaydırın veya filtreyi kullanarak Bildirim Hizmeti Uzantısı'nı seçin. Sonraki'yi tıklayın.
- Bir ürün adı ekleyin (bu eğiticiyle devam etmek için "ImageDescription" kullanın), dili Objective-C olarak ayarlayın ve Finish'i (Son) tıklayın.
- Etkinleştir'i tıklayarak şemayı etkinleştirin.
2. Adım - Podfile'a hedef ekleyin
Yeni uzantınızı Podfile'a ekleyerek Firebase/Messaging
kapsülüne erişimi olduğundan emin olun:
Navigator'da Podfile'ı açın: Pods > Podfile
Dosyanın alt kısmına gidin ve aşağıdakileri ekleyin:
target 'ImageNotification' do use_frameworks! pod 'Firebase/Auth' # Add this line if you are using FirebaseAuth phone authentication pod 'Firebase/Messaging' end
ios
veyamacos
dizinindenpod install
aracını kullanarak kapsüllerinizi yükleyin veya güncelleyin.
3. Adım - Uzantı yardımcısını kullanın
Bu noktada, her şey normal şekilde çalışıyor olmalıdır. Son adım, uzantı yardımcısını çağırmaktır.
Gezinme panelinden ImageBildirim uzantınızı seçin.
NotificationService.m
dosyasını açın.Dosyanın üst kısmında, aşağıda gösterildiği gibi
NotificationService.h
öğesinin hemen ardındanFirebaseMessaging.h
dosyasını içe aktarın.NotificationService.m
içeriğini şununla değiştir:#import "NotificationService.h" #import "FirebaseMessaging.h" #import "FirebaseAuth.h" // Add this line if you are using FirebaseAuth phone authentication #import <UIKit/UIKit.h> // Add this line if you are using FirebaseAuth phone authentication @interface NotificationService () @property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); @property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; @end @implementation NotificationService /* Uncomment this if you are using Firebase Auth - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options { if ([[FIRAuth auth] canHandleURL:url]) { return YES; } return NO; } - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts { for (UIOpenURLContext *urlContext in URLContexts) { [FIRAuth.auth canHandleURL:urlContext.URL]; } } */ - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { self.contentHandler = contentHandler; self.bestAttemptContent = [request.content mutableCopy]; // Modify the notification content here... [[FIRMessaging extensionHelper] populateNotificationContent:self.bestAttemptContent withContentHandler:contentHandler]; } - (void)serviceExtensionTimeWillExpire { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. self.contentHandler(self.bestAttemptContent); } @end
4. Adım - Resmi yüke ekleyin
Bildirim yükünüze artık bir resim ekleyebilirsiniz. Gönderme isteği oluşturma ile ilgili iOS dokümanlarına bakın. Cihazın maksimum 300 KB resim boyutunu zorunlu kıldığını unutmayın.