Bir cihazın durumuna bağlı olarak, gelen mesajlar farklı şekilde işlenir. Bu senaryoları ve FCM'yi kendi uygulamanıza nasıl entegre edeceğinizi anlamak için öncelikle bir cihazın içinde olabileceği çeşitli durumları belirlemek önemlidir:
Durum | Tanım |
---|---|
ön plan | Uygulama açık, görünümde ve kullanımda olduğunda. |
Arka plan | Uygulama açıkken, ancak arka planda (küçültülmüş) olduğunda. Bu 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ılmış | Cihaz kilitliyken veya uygulama çalışmıyorken. |
Uygulamanın FCM yoluyla mesaj yüklerini alabilmesi için karşılanması gereken birkaç ön koşul vardır:
- Uygulamanın en az bir kez açılmış olması gerekir (FCM'ye kaydolmaya izin vermek için).
- iOS'ta, kullanıcı uygulamayı uygulama değiştiriciden hızlıca kaydırırsa, arka plan mesajlarının yeniden çalışmaya başlaması için uygulamanın manuel olarak yeniden açılması gerekir.
- Android'de kullanıcı, uygulamadan cihaz ayarlarından zorla çıkarsa mesajların çalışmaya başlaması için uygulamanın manuel olarak yeniden açılması gerekir.
- Web'de, web push sertifikanızla (
getToken()
kullanarak) bir belirteç istemiş olmanız gerekir.
Mesaj almak için izin isteme (Apple ve Web)
iOS, macOS ve web'de, FCM yüklerinin cihazınıza alınabilmesi için öncelikle kullanıcıdan izin almanız gerekir.
firebase_messaging
paketi, requestPermission
yöntemi aracılığıyla izin istemek için basit bir API sağlar. Bu API, bildirim yükleri içeren mesajlaşmanın bir sesi tetikleyip tetikleyemeyeceği veya Siri aracılığıyla mesajları okuyup okuyamayacağı gibi, talep etmek istediğiniz izin türlerini tanımlayan bir dizi adlandırılmış bağımsız değişkeni kabul eder. Varsayılan olarak, yöntem mantıklı varsayılan izinler ister. Referans API, her bir iznin ne için olduğuna dair eksiksiz belgeler sağlar.
Başlamak için, uygulamanızdan yöntemi çağırın (iOS'ta yerel bir modal görüntülenecek, web'de tarayıcının yerel API akışı tetiklenecektir):
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 vermemeyi henüz seçmedi. -
provisional
: Kullanıcı geçici izin verdi
NotificationSettings
diğer özellikler, geçerli cihazda belirli bir iznin etkinleştirilip etkinleştirilmediğini, devre dışı bırakıldığını veya desteklenmediğini 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ürlerinin gelen yüklerini işlemek 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 nereden geldiği, benzersiz kimliği, gönderme zamanı, bir bildirim içerip içermediği ve daha fazlası gibi çeşitli bilgileri detaylandıran bir RemoteMessage
içerir. Mesaj, uygulamanız ön plandayken alındığından, Flutter uygulamanızın durumuna ve içeriğine doğrudan erişebilirsiniz.
Ön Plan ve Bildirim mesajları
Uygulama ön plandayken gelen bildirim mesajları, hem Android hem de iOS'ta varsayılan olarak görünür bir bildirim göstermez. Ancak, bu davranışı geçersiz kılmak mümkündür:
- Android'de "Yüksek Öncelikli" bir bildirim kanalı oluşturmalısınız.
- iOS'ta uygulamanın sunum seçeneklerini güncelleyebilirsiniz.
arka plan mesajları
Arka plan mesajlarını işleme süreci, yerel (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, uygulamanız çalışmıyorken bile mesajları işlemenize olanak tanıyan bir izolasyon oluşturulur (yalnızca Android, iOS/macOS ayrı bir izolasyon gerektirmez).
Arka plan ileti işleyiciniz hakkında akılda tutulması gereken birkaç şey vardır:
- Anonim bir işlev olmamalıdır.
- Üst düzey bir işlev olmalıdır (örneğin, başlatma gerektiren bir sınıf yöntemi değil).
- Flutter sürüm 3.3.0 veya üzerini kullanırken, mesaj işleyiciye işlev bildiriminin hemen üzerinde
@pragma('vm:entry-point')
ile açıklama eklenmelidir (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ınızın dışında kendi izolasyonunda çalıştığından, uygulama durumunu güncellemek veya UI'yi etkileyen herhangi bir mantığı yürütmek mümkün değildir. Bununla birlikte, HTTP istekleri gibi mantık gerçekleştirebilir, IO işlemleri gerçekleştirebilir (örn. yerel depolamayı güncelleme), diğer eklentilerle iletişim kurabilirsiniz vb.
Ayrıca mantığınızı en kısa sürede tamamlamanız tavsiye edilir. Uzun, yoğun görevler yürütmek cihaz performansını etkiler ve işletim sisteminin işlemi sonlandırmasına neden olabilir. Görevler 30 saniyeden uzun sürerse, cihaz işlemi otomatik olarak sonlandırabilir.
ağ
Web'de, arka planda çalışan bir JavaScript Hizmet Çalışanı yazın. Arka plan mesajlarını işlemek için servis çalışanını kullanın.
Başlamak için web
dizininizde yeni bir dosya oluşturun ve onu 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);
});
Dosyanın hem uygulamayı hem de mesajlaşma SDK'larını içe aktarması, Firebase'i başlatması ve messaging
değişkenini göstermesi gerekir.
Daha sonra, çalışan kayıtlı olmalıdır. 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>
Daha sonra Flutter uygulamanızı yeniden başlatın. Çalışan kaydedilecek ve herhangi bir arka plan mesajı bu dosya aracılığıyla işlenecektir.
İşleme Etkileşimi
Bildirimler görünür bir ipucu olduğundan, kullanıcıların onlarla etkileşim kurması (basarak) yaygındır. Hem Android hem de iOS'ta varsayılan davranış, uygulamayı açmaktır. Uygulama sonlandırılırsa başlatılacaktır; arka planda ise ön plana getirilir.
Bir bildirimin içeriğine bağlı olarak, uygulama açıldığında kullanıcının etkileşimini yönetmek isteyebilirsiniz. Örneğin, bir bildirim yoluyla yeni bir sohbet mesajı gönderilirse ve kullanıcı buna basarsa, uygulama açıldığında belirli bir sohbeti açmak isteyebilirsiniz.
firebase-messaging
paketi, bu etkileşimi işlemek için iki yol sağlar:
-
getInitialMessage()
: Uygulama sonlandırılmış bir durumdan açılırsa,RemoteMessage
içeren birFuture
döndürülür. Tüketildiğinde,RemoteMessage
kaldırılacaktır. -
onMessageOpenedApp
: Uygulama bir arka plan durumundan açıldığında birRemoteMessage
gönderen birStream
.
Kullanıcılarınız için sorunsuz bir kullanıcı deneyimi sağlamak için her iki senaryonun da ele alınması önerilir. Aşağıdaki kod örneği, bunun nasıl başarılabileceğini özetlemektedir:
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 aldığınız, uygulama kurulumunuza bağlıdır. Yukarıdaki örnek, bir StatefulWidget kullanan temel bir çizimi göstermektedir.
Mesajları Yerelleştir
Yerelleştirilmiş dizeleri iki farklı şekilde gönderebilirsiniz:
- Kullanıcılarınızın her birinin tercih ettiği dili sunucunuzda saklayın ve her dil için özelleştirilmiş bildirimler gönderin
- Uygulamanıza yerelleştirilmiş dizeler ekleyin 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
dosyasında varsayılan dil mesajlarınızı belirtin:<string name="notification_title">Hello world</string> <string name="notification_message">This is a message</string>
values- language
dizininde çevrilmiş mesajları belirtin. Örneğin,resources/values-fr/strings.xml
içinde Fransızca iletileri belirtin:<string name="notification_title">Bonjour le monde</string> <string name="notification_message">C'est un message</string>
Sunucu yükünde,
title
,message
vebody
anahtarlarını kullanmak yerine, yerelleştirilmiş mesajınız içintitle_loc_key
vebody_loc_key
kullanın ve bunları görüntülemek istediğiniz mesajınname
özniteliğine ayarlayın.Mesaj yükü şöyle görünür:
{ "data": { "title_loc_key": "notification_title", "body_loc_key": "notification_message" } }
iOS
Varsayılan dil mesajlarınızı
Base.lproj/Localizable.strings
içinde belirtin:"NOTIFICATION_TITLE" = "Hello World"; "NOTIFICATION_MESSAGE" = "This is a message";
Çevrilen iletileri
language .lproj
dizininde belirtin. Örneğin,fr.lproj/Localizable.strings
içinde Fransızca mesajları belirtin:"NOTIFICATION_TITLE" = "Bonjour le monde"; "NOTIFICATION_MESSAGE" = "C'est un message";
Mesaj yükü şöyle görünür:
{ "data": { "title_loc_key": "NOTIFICATION_TITLE", "body_loc_key": "NOTIFICATION_MESSAGE" } }
Mesaj teslimi verilerini dışa aktarmayı etkinleştir
Daha fazla analiz için mesaj verilerinizi BigQuery'ye aktarabilirsiniz. BigQuery, verileri BigQuery SQL kullanarak analiz etmenize, başka bir bulut sağlayıcıya aktarmanıza veya verileri özel makine öğrenimi modelleriniz için kullanmanıza olanak tanır. BigQuery'ye dışa aktarma, mesaj türünden veya mesajın API veya Notifications oluşturucu aracılığıyla gönderilip gönderilmediğinden bağımsız olarak, 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ı izleyin:
Android
Aşağıdaki kodu kullanabilirsiniz:
await FirebaseMessaging.instance.setDeliveryMetricsExportToBigQuery(true);
iOS
iOS için AppDelegate.m
dosyasını aşağıdaki içerikle değiştirmeniz gerekmektedir.
#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
ağ
Web için, SDK'nın v9 sürümünü kullanmak üzere hizmet çalışanınızı değiştirmeniz gerekir. v9 sürümünün paketlenmesi gerekir, bu nedenle hizmet çalışanının çalışmasını sağlamak için örneğin esbuild
gibi bir paketleyici kullanmanız gerekir. Bunu nasıl başaracağınızı görmek için örnek uygulamaya bakın.
v9 SDK'ya geçtikten sonra aşağıdaki kodu kullanabilirsiniz:
import {
experimentalSetDeliveryMetricsExportedToBigQueryEnabled,
getMessaging,
} from 'firebase/messaging/sw';
...
const messaging = getMessaging(app);
experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);
Hizmet çalışanınızın yeni sürümünü web
klasörüne aktarmak için yarn build
komutunu çalıştırmayı unutmayın.
Resimleri iOS'ta bildirimlerde göster
Apple aygıtlarında, gelen FCM Bildirimlerinin FCM yükünden görüntüleri göstermesi için ek bir bildirim hizmeti uzantısı eklemeniz ve uygulamanızı bunu kullanacak şekilde yapılandırmanız gerekir.
Firebase telefon kimlik doğrulamasını kullanıyorsanız, Firebase Kimlik Doğrulama bölmesini Pod dosyanıza eklemelisiniz.
1. Adım - Bir bildirim hizmeti uzantısı ekleyin
- Xcode'da, Dosya > Yeni > Hedef...'e tıklayın.
- Bir model, olası hedeflerin bir listesini sunacaktır; aşağı kaydırın veya Bildirim Hizmeti Uzantısı'nı seçmek için filtreyi kullanın. İleri'yi tıklayın.
- Bir ürün adı ekleyin (bu öğreticiyi takip etmek için "ImageNotification" kullanın), dili Objective-C olarak ayarlayın ve Bitir'i tıklayın.
- Etkinleştir'e tıklayarak şemayı etkinleştirin.
Adım 2 - Pod dosyasına hedef ekleyin
Yeni uzantınızı Pod dosyasına ekleyerek Firebase/Messaging
bölmesine erişebildiğinden emin olun:
Navigator'dan Podfile'ı açın: Pods > Podfile
Dosyanın en altına gidin ve şunu 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
kullanarak bölmelerinizi kurun veya güncelleyin.
3. Adım - Uzantı yardımcısını kullanın
Bu noktada, her şey hala normal çalışıyor olmalıdır. Son adım, uzantı yardımcısını çağırmaktır.
Gezginden ImageNotification uzantınızı seçin
NotificationService.m
dosyasını açın.Dosyanın en üstünde, aşağıda gösterildiği gibi
NotificationService.h
hemen sonraFirebaseMessaging.h
içe aktarın.NotificationService.m
içeriğini şununla değiştirin:#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
Adım 4 - Görüntüyü yüke ekleyin
Bildirim yükünüze artık bir resim ekleyebilirsiniz. Bir gönderme isteğinin nasıl oluşturulacağına ilişkin iOS belgelerine bakın. Cihaz tarafından maksimum 300 KB görüntü boyutunun zorunlu kılındığını unutmayın.