Apple platformlarında birden çok cihaza ileti gönderme

Bir mesajı birden fazla cihazı hedefleyecek şekilde göndermek için konu mesajlaşmayı kullanın. Bu özellik, belirli bir konuyu etkinleştirmiş birden fazla cihaza mesaj göndermenize olanak tanır.

Bu eğitimde, FCM için Admin SDK veya REST API'yi kullanarak uygulama sunucunuzdan konu mesajları göndermeye, bunları bir Apple uygulamasında almaya ve işlemeye odaklanılmaktadır. Bu sayfada, kurulumdan doğrulamaya kadar bu işlemi gerçekleştirmek için gereken tüm adımlar listelenmiştir. Bu nedenle, FCM için bir Apple istemci uygulaması kurduysanız veya İlk Mesajınızı Gönderme adımlarını tamamladıysanız daha önce tamamladığınız adımlar da bu sayfada yer alabilir.

Firebase'i Apple projenize ekleme

Bu bölümde, uygulamanız için diğer Firebase özelliklerini etkinleştirdiyseniz tamamlamış olabileceğiniz görevler ele alınmaktadır. Özellikle FCM için APNs kimlik doğrulama anahtarınızı yüklemeniz ve uzaktan bildirimlere kaydolmanız gerekir.

Ön koşullar

  • Aşağıdakileri yükleyin:

    • Xcode 16.2 veya sonraki sürümler
  • Projenizin aşağıdaki koşulları karşıladığından emin olun:

    • Projeniz aşağıdaki platform sürümlerini veya daha yenilerini hedeflemelidir:
      • iOS 13
      • macOS 10.15
      • tvOS 13
      • watchOS 7
  • Uygulamanızı çalıştırmak için fiziksel bir Apple cihazı ayarlayın ve şu görevleri tamamlayın:

    • Apple geliştirici hesabınız için Apple Anında Bildirim Kimlik Doğrulama Anahtarı edinin.
    • XCode'da App > Capabilities altında push bildirimlerini etkinleştirin.

Henüz bir Xcode projeniz yoksa ve yalnızca bir Firebase ürününü denemek istiyorsanız hızlı başlangıç örneklerimizden birini indirebilirsiniz.

Firebase projesi oluşturma

Firebase'i Apple uygulamanıza ekleyebilmeniz için öncelikle uygulamanıza bağlanacak bir Firebase projesi oluşturmanız gerekir. Firebase projeleri hakkında daha fazla bilgi edinmek için Firebase projelerini anlama başlıklı makaleyi inceleyin.

Uygulamanızı Firebase'e kaydetme

Firebase'i Apple uygulamanızda kullanmak için uygulamanızı Firebase projenize kaydetmeniz gerekir. Uygulamanızı kaydetme işlemi genellikle uygulamanızı projenize "ekleme" olarak adlandırılır.

  1. Firebase konsoluna gidin.

  2. Kurulum iş akışını başlatmak için projeye genel bakış sayfasının ortasındaki iOS+ simgesini tıklayın.

    Firebase projenize zaten bir uygulama eklediyseniz platform seçeneklerini görüntülemek için Uygulama ekle'yi tıklayın.

  3. Uygulamanızın paket kimliğini paket kimliği alanına girin.

  4. (İsteğe bağlı) Diğer uygulama bilgilerini girin: Uygulama takma adı ve App Store kimliği.

  5. Uygulamayı kaydet'i tıklayın.

Firebase yapılandırma dosyası ekleme

  1. Uygulamanızın Firebase yapılandırma dosyasını (GoogleService-Info.plist) almak için GoogleService-Info.plist'i indir'i tıklayın.

  2. Yapılandırma dosyanızı Xcode projenizin kök dizinine taşıyın. İstenirse yapılandırma dosyasını tüm hedeflere eklemeyi seçin.

Projenizde birden fazla paket kimliği varsa her paketi Firebase konsolunda kayıtlı bir uygulamayla ilişkilendirmeniz gerekir. Böylece her uygulamanın kendi GoogleService-Info.plist dosyası olabilir.

Uygulamanıza Firebase SDK'larını ekleme

Firebase bağımlılarını yükleyip yönetmek için Swift Package Manager'ı kullanın.

  1. Xcode'da, uygulamanız açıkken File > Add Packages (Dosya > Paket Ekle) seçeneğine gidin.
  2. İstendiğinde Firebase Apple platformları SDK deposunu ekleyin:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Firebase Cloud Messaging kitaplığını seçin.
  5. -ObjC işaretini hedefinizin derleme ayarlarının Other Linker Flags (Diğer Bağlayıcı İşaretleri) bölümüne ekleyin.
  6. Firebase Cloud Messaging ile en iyi deneyimi elde etmek için Firebase projenizde Google Analytics'ı etkinleştirmenizi ve uygulamanıza Google Analytics için Firebase SDK'sını eklemenizi öneririz. IDFA toplama özelliği olmayan veya IDFA toplama özelliği olan kitaplığı seçebilirsiniz. Firebase SDK'sında Google Analytics için modüllerin en son düzenlenmesi ile ilgili SSS bölümümüzü inceleyin.
  7. İşlem tamamlandığında Xcode otomatik olarak arka planda bağımlılarınızı çözümlemeye ve indirmeye başlar.

APNs kimlik doğrulama anahtarınızı yükleyin

APNs kimlik doğrulama anahtarınızı Firebase'e yükleyin. Henüz bir APNs kimlik doğrulama anahtarınız yoksa Apple Developer Member Center'da bir tane oluşturduğunuzdan emin olun.

  1. Firebase konsolundaki projenizde dişli simgesini, Proje Ayarları'nı ve ardından Cloud Messaging sekmesini seçin.

  2. iOS uygulama yapılandırması bölümündeki APNs kimlik doğrulama anahtarı altında, Yükle düğmesini tıklayın.

  3. Anahtarınızı kaydettiğiniz konuma gidin, anahtarınızı seçin ve 'ı tıklayın. Anahtarın anahtar kimliğini ekleyin ( Apple Developer Member Center'da bulunur) ve Yükle'yi tıklayın.

Uygulamanızda Firebase'i başlatma

Uygulamanıza Firebase başlatma kodu eklemeniz gerekir. Firebase modülünü içe aktarın ve gösterildiği gibi paylaşılan bir örnek yapılandırın:

  1. FirebaseCore modülünü UIApplicationDelegate dosyanıza ve uygulama temsilcinizin kullandığı diğer Firebase modüllerine aktarın. Örneğin, Cloud Firestore ve Authentication kullanmak için:

    SwiftUI

    import SwiftUI
    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Swift

    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Objective-C

    @import FirebaseCore;
    @import FirebaseFirestore;
    @import FirebaseAuth;
    // ...
          
  2. Uygulama temsilcinizin application(_:didFinishLaunchingWithOptions:) yönteminde paylaşılan bir FirebaseApp örneği yapılandırın:

    SwiftUI

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    Swift

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
  3. SwiftUI kullanıyorsanız bir uygulama temsilcisi oluşturmanız ve bunu App yapınızda UIApplicationDelegateAdaptor veya NSApplicationDelegateAdaptor aracılığıyla eklemeniz gerekir. Ayrıca uygulama temsilcisi karıştırmayı da devre dışı bırakmanız gerekir. Daha fazla bilgi için SwiftUI talimatlarına bakın.

    SwiftUI

    @main
    struct YourApp: App {
      // register app delegate for Firebase setup
      @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
      var body: some Scene {
        WindowGroup {
          NavigationView {
            ContentView()
          }
        }
      }
    }
          

Uzak bildirimlere kaydolma

Uygulama akışınızda başlangıçta veya istediğiniz noktada uygulamanızı uzaktan bildirimler için kaydedin. Aşağıdaki gibi registerForRemoteNotifications çağrısı yapın:

Swift

UNUserNotificationCenter.current().delegate = self

let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
  options: authOptions,
  completionHandler: { _, _ in }
)

application.registerForRemoteNotifications()

Objective-C

[UNUserNotificationCenter currentNotificationCenter].delegate = self;
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
    UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter]
    requestAuthorizationWithOptions:authOptions
    completionHandler:^(BOOL granted, NSError * _Nullable error) {
      // ...
    }];

[application registerForRemoteNotifications];

İstemci uygulamasını bir konuya abone etme

İstemci uygulamaları, mevcut herhangi bir konuya abone olabilir veya yeni bir konu oluşturabilir. Bir istemci uygulaması yeni bir konu adına (Firebase projenizde henüz mevcut olmayan bir ad) abone olduğunda FCM içinde bu ada sahip yeni bir konu oluşturulur ve daha sonra herhangi bir istemci bu konuya abone olabilir.

Bir konuya abone olmak için uygulamanızın ana iş parçacığından abonelik yöntemini çağırın (FCM iş parçacığı açısından güvenli değildir). Abonelik isteği ilk başta başarısız olursa FCM otomatik olarak yeniden denenir. Aboneliğin tamamlanamadığı durumlarda, abonelik, tamamlanma işleyicisinde yakalayabileceğiniz bir hata verir.

Swift

Messaging.messaging().subscribe(toTopic: "weather") { error in
  print("Subscribed to weather topic")
}

Objective-C

[[FIRMessaging messaging] subscribeToTopic:@"weather"
                                completion:^(NSError * _Nullable error) {
  NSLog(@"Subscribed to weather topic");
}];

Bu çağrı, FCM arka uca eşzamansız bir istekte bulunur ve istemciyi belirtilen konuya abone eder. subscribeToTopic:topic işlevini çağırmadan önce istemci uygulaması örneğinin, geri çağırma didReceiveRegistrationToken aracılığıyla bir kayıt jetonu aldığından emin olun.

Uygulama her başlatıldığında FCM, istenen tüm konulara abone olunduğundan emin olur. Abonelikten çıkmak için unsubscribeFromTopic:topic numaralı telefonu arayın. FCM, arka planda konu aboneliğinden çıkar.

Konu mesajlarını alma ve işleme

FCM, konu iletilerini diğer aşağı akış iletileriyle aynı şekilde dağıtır.

application(_:didReceiveRemoteNotification:fetchCompletionHandler:) işaretlemesini gösterildiği gibi uygulayın:

Swift

func application(_ application: UIApplication,
                 didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
  -> UIBackgroundFetchResult {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // Print message ID.
  if let messageID = userInfo[gcmMessageIDKey] {
    print("Message ID: \(messageID)")
  }

  // Print full message.
  print(userInfo)

  return UIBackgroundFetchResult.newData
}

Objective-C

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // ...

  // Print full message.
  NSLog(@"%@", userInfo);

  completionHandler(UIBackgroundFetchResultNewData);
}

Gönderme istekleri oluşturma

Bir konuyu istemci tarafında istemci uygulaması örneklerini konuya abone ederek veya sunucu API'si aracılığıyla oluşturduktan sonra konuya mesaj gönderebilirsiniz. FCM için ilk kez gönderme isteği oluşturuyorsanız önemli arka plan ve kurulum bilgileri için sunucu ortamınız ve FCM ile ilgili kılavuza bakın.

Arka uçtaki gönderme mantığınızda, istediğiniz konu adını aşağıdaki gibi belirtin:

Node.js

// The topic name can be optionally prefixed with "/topics/".
const topic = 'highScores';

const message = {
  data: {
    score: '850',
    time: '2:45'
  },
  topic: topic
};

// Send a message to devices subscribed to the provided topic.
getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

// The topic name can be optionally prefixed with "/topics/".
String topic = "highScores";

// See documentation on defining a message payload.
Message message = Message.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .setTopic(topic)
    .build();

// Send a message to the devices subscribed to the provided topic.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

Python

# The topic name can be optionally prefixed with "/topics/".
topic = 'highScores'

# See documentation on defining a message payload.
message = messaging.Message(
    data={
        'score': '850',
        'time': '2:45',
    },
    topic=topic,
)

# Send a message to the devices subscribed to the provided topic.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Go

// The topic name can be optionally prefixed with "/topics/".
topic := "highScores"

// See documentation on defining a message payload.
message := &messaging.Message{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Topic: topic,
}

// Send a message to the devices subscribed to the provided topic.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// The topic name can be optionally prefixed with "/topics/".
var topic = "highScores";

// See documentation on defining a message payload.
var message = new Message()
{
    Data = new Dictionary<string, string>()
    {
        { "score", "850" },
        { "time", "2:45" },
    },
    Topic = topic,
};

// Send a message to the devices subscribed to the provided topic.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
  "message":{
    "topic" : "foo-bar",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message"
      }
   }
}

cURL komutu:

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
  "message": {
    "topic" : "foo-bar",
    "notification": {
      "body": "This is a Firebase Cloud Messaging Topic Message!",
      "title": "FCM Message"
    }
  }
}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Bir konu kombinasyonuna mesaj göndermek için hedef konuları belirten bir Boole ifadesi olan koşul belirtin. Örneğin, aşağıdaki koşul, mesajları TopicA'ya abone olan ve TopicB veya TopicC cihazlarına gönderir:

"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"

FCM önce parantez içindeki koşulları değerlendirir, ardından ifadeyi soldan sağa doğru değerlendirir. Yukarıdaki ifadede, herhangi bir konuya abone olan kullanıcı mesajı almaz. Aynı şekilde, TopicA kanalına abone olmayan kullanıcılar da mesajı almaz. Bu kombinasyonlar, bu özelliği destekler:

  • TopicA ve TopicB
  • TopicA ve TopicC

Koşullu ifadenize en fazla beş konu ekleyebilirsiniz.

Bir koşula göndermek için:

Node.js

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
const condition = '\'stock-GOOG\' in topics || \'industry-tech\' in topics';

// See documentation on defining a message payload.
const message = {
  notification: {
    title: '$FooCorp up 1.43% on the day',
    body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
  },
  condition: condition
};

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
String condition = "'stock-GOOG' in topics || 'industry-tech' in topics";

// See documentation on defining a message payload.
Message message = Message.builder()
    .setNotification(Notification.builder()
        .setTitle("$GOOG up 1.43% on the day")
        .setBody("$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.")
        .build())
    .setCondition(condition)
    .build();

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

Python

# Define a condition which will send to devices which are subscribed
# to either the Google stock or the tech industry topics.
condition = "'stock-GOOG' in topics || 'industry-tech' in topics"

# See documentation on defining a message payload.
message = messaging.Message(
    notification=messaging.Notification(
        title='$GOOG up 1.43% on the day',
        body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
    ),
    condition=condition,
)

# Send a message to devices subscribed to the combination of topics
# specified by the provided condition.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Go

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
condition := "'stock-GOOG' in topics || 'industry-tech' in topics"

// See documentation on defining a message payload.
message := &messaging.Message{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Condition: condition,
}

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
var condition = "'stock-GOOG' in topics || 'industry-tech' in topics";

// See documentation on defining a message payload.
var message = new Message()
{
    Notification = new Notification()
    {
        Title = "$GOOG up 1.43% on the day",
        Body = "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
    },
    Condition = condition,
};

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
   "message":{
    "condition": "'dogs' in topics || 'cats' in topics",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message",
    }
  }
}

cURL komutu:

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
  "notification": {
    "title": "FCM Message",
    "body": "This is a Firebase Cloud Messaging Topic Message!",
  },
  "condition": "'dogs' in topics || 'cats' in topics"
}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Sonraki adımlar

  • İstemci uygulaması örneklerini konulara abone etmek ve diğer yönetim görevlerini gerçekleştirmek için sunucunuzu kullanabilirsiniz. Sunucudaki konu aboneliklerini yönetme başlıklı makaleyi inceleyin.