Buka konsol

Mengirim pesan ke banyak perangkat di iOS

Firebase Cloud Messaging menyediakan 2 cara untuk menargetkan pesan ke beberapa perangkat:

  • Messaging topik dapat digunakan untuk mengirim pesan ke beberapa perangkat yang mengikuti topik tertentu.
  • Messaging grup perangkat dapat Anda gunakan untuk mengirim 1 pesan ke beberapa instance aplikasi yang berjalan di beberapa perangkat milik sebuah grup.

Tutorial ini berfokus pada pengiriman pesan topik dari server aplikasi Anda yang menggunakan protokol HTTP atau XMPP untuk FCM, dan menerima serta menanganinya dalam aplikasi iOS. Halaman ini membahas semua langkah untuk mencapainya, mulai dari penyiapan hingga verifikasi. Jadi, halaman ini dapat mencakup langkah-langkah yang telah Anda selesaikan jika Anda telah menyiapkan aplikasi klien iOS untuk FCM atau telah menyelesaikan langkah-langkah untuk Mengirim Pesan Pertama.

Menambahkan Firebase ke project iOS Anda

Bagian ini membahas tugas yang mungkin telah Anda selesaikan jika Anda telah mengaktifkan fitur Firebase lain untuk aplikasi Anda. Khusus untuk FCM, Anda harus mengupload kunci autentikasi APN dan mendaftar untuk menerima notifikasi jarak jauh.

Prasyarat

  • Instal Xcode 10.1 atau versi yang lebih baru.

  • Instal CocoaPods 1.4.0 atau versi yang lebih baru.

  • Buka project Anda di Xcode.

    • Project Anda harus menargetkan iOS 8 atau versi yang lebih baru.

    • Project Swift harus menggunakan Swift 3.0 atau versi yang lebih baru.

  • Siapkan perangkat iOS fisik atau simulator iOS untuk menjalankan aplikasi Anda.

    • Untuk Cloud Messaging, Anda memerlukan:

      • Perangkat iOS fisik
      • Kunci Autentikasi Apple Notifikasi Push untuk akun Developer Apple
      • Di Xcode, aktifkan Notifikasi Push di App > Capabilities.
    • Untuk semua produk Firebase lainnya, Anda dapat menggunakan perangkat iOS fisik atau simulator iOS.

  • Login ke Firebase menggunakan Akun Google Anda.

Jika belum memiliki project Xcode, Anda dapat mendownload salah satu contoh quickstart kami jika Anda hanya ingin mencoba produk Firebase.

Membuat project Firebase

Sebelum dapat menambahkan Firebase ke aplikasi iOS, Anda harus membuat project Firebase untuk terhubung ke aplikasi iOS. Kunjungi Memahami Project Firebase untuk mempelajari tentang project Firebase lebih lanjut.

Mendaftarkan aplikasi Anda dengan Firebase

Setelah memiliki project Firebase, Anda dapat menambahkan aplikasi iOS ke dalamnya.

Buka bagian Memahami Project Firebase untuk mempelajari lebih lanjut praktik terbaik dan pertimbangan dalam menambahkan aplikasi ke project Firebase, termasuk cara menangani beberapa variasi build.

  1. Di tengah halaman ringkasan project Firebase console, klik ikon iOS untuk meluncurkan alur kerja penyiapan.

    Jika Anda sudah menambahkan aplikasi ke project Firebase, klik Tambahkan aplikasi untuk menampilkan opsi platform.

  2. Masukkan ID paket aplikasi Anda di kolom ID paket iOS.

    • Temukan ID paket ini dengan membuka aplikasi Anda di XCode, lalu akses tab Umum di direktori Runner level teratas. Nilai kolom ID Paket adalah ID paket iOS (misalnya, com.yourcompany.yourproject).
  3. (Opsional) Masukkan informasi aplikasi lain seperti yang diminta oleh alur kerja penyiapan.

  4. Klik Daftarkan aplikasi.

Menambahkan file konfigurasi Firebase

  1. Klik Download GoogleService-Info.plist untuk mendapatkan file konfigurasi iOS Firebase Anda (GoogleService-Info.plist).

    • Anda dapat mendownload file konfigurasi iOS Firebase lagi kapan saja.

    • Pastikan file konfigurasi tidak ditambahkan dengan karakter tambahan, seperti (2).

  2. Pindahkan file konfigurasi ke root project Xcode Anda. Jika diminta, pilih untuk menambahkan file konfigurasi ke semua target.

Jika Anda memiliki beberapa ID paket dalam project, Anda harus mengaitkan setiap ID paket dengan aplikasi yang terdaftar di Firebase console sehingga setiap aplikasi dapat memiliki file GoogleService-Info.plist sendiri.

Menambahkan Firebase SDK ke aplikasi Anda

Sebaiknya gunakan CocoaPods untuk menginstal library Firebase. Namun, jika tidak ingin menggunakan CocoaPods, Anda bisa mengintegrasikan framework SDK secara langsung.

Perlu diingat, jika Anda menggunakan salah satu contoh panduan memulai, project Xcode dan Podfile (dengan pod) sudah tersedia. Meskipun demikian, Anda tetap harus menambahkan file konfigurasi Firebase dan menginstal pod.

Anda dapat menambahkan produk Firebase yang didukung ke aplikasi iOS.

  1. Buat Podfile jika Anda belum memilikinya:

    cd your-project-directory
    pod init
  2. Tambahkan pod yang ingin digunakan dalam aplikasi Anda ke Podfile tersebut.

    Untuk mendapatkan pengalaman yang optimal saat menggunakan Firebase Cloud Messaging, sebaiknya aktifkan Google Analytics di project Anda. Sebagai bagian dari penyiapan Google Analytics, Anda perlu menambahkan paket Firebase SDK untuk Google Analytics ke aplikasi Anda.

    Analytics diaktifkan

    # Add the Firebase pod for Google Analytics
    pod 'Firebase/Analytics'
    # Add the pod for Firebase Cloud Messaging pod 'Firebase/Messaging'

    Analytics tidak diaktifkan

    # Add the pod for Firebase Cloud Messaging
    pod 'Firebase/Messaging'

  3. Instal pod, lalu buka file .xcworkspace untuk melihat project di Xcode:

    pod install
    open your-project.xcworkspace

Mengupload kunci autentikasi APN Anda

Upload kunci autentikasi APN Anda ke Firebase. Jika Anda belum memiliki kunci autentikasi APN, baca cara Mengonfigurasi APN dengan FCM.

  1. Pada project Anda di Firebase console, pilih ikon roda gigi, pilih Setelan Project, kemudian pilih tab Cloud Messaging.

  2. Di kunci autentikasi APN di bagian konfigurasi aplikasi iOS, klik tombol Upload.

  3. Buka lokasi tempat Anda menyimpan kunci, pilih kunci tersebut, lalu klik Buka. Tambahkan ID kunci untuk kunci tersebut (tersedia di Certificates, Identifiers & Profiles di Apple Developer Member Center) lalu klik Upload.

Menginisialisasi Firebase di aplikasi Anda

Anda harus menambahkan kode inisialisasi Firebase ke aplikasi. Impor modul Firebase dan konfigurasi instance bersama seperti berikut ini:

  1. Impor modul Firebase di UIApplicationDelegate Anda:

    Swift

    import Firebase

    Objective-C

    @import Firebase;
  2. Konfigurasikan FirebaseApp instance bersama, biasanya ada dalam metode application:didFinishLaunchingWithOptions: aplikasi Anda:

    Swift

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

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];

Mendaftar untuk notifikasi jarak jauh

Baik saat startup maupun pada titik lain yang Anda inginkan dalam alur proses aplikasi, daftarkan aplikasi Anda untuk mendapatkan notifikasi jarak jauh. Panggil registerForRemoteNotifications sebelum memanggil .

Swift

if #available(iOS 10.0, *) {
  // For iOS 10 display notification (sent via APNS)
  UNUserNotificationCenter.current().delegate = self

  let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
  UNUserNotificationCenter.current().requestAuthorization(
    options: authOptions,
    completionHandler: {_, _ in })
} else {
  let settings: UIUserNotificationSettings =
  UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
  application.registerUserNotificationSettings(settings)
}

application.registerForRemoteNotifications()

Objective-C

if ([UNUserNotificationCenter class] != nil) {
  // iOS 10 or later
  // For iOS 10 display notification (sent via APNS)
  [UNUserNotificationCenter currentNotificationCenter].delegate = self;
  UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
      UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
  [[UNUserNotificationCenter currentNotificationCenter]
      requestAuthorizationWithOptions:authOptions
      completionHandler:^(BOOL granted, NSError * _Nullable error) {
        // ...
      }];
} else {
  // iOS 10 notifications aren't available; fall back to iOS 8-9 notifications.
  UIUserNotificationType allNotificationTypes =
  (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
  UIUserNotificationSettings *settings =
  [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
  [application registerUserNotificationSettings:settings];
}

[application registerForRemoteNotifications];

Membuat aplikasi klien berlangganan topik

Aplikasi klien dapat berlangganan ke topik yang ada atau membuat topik baru. Jika aplikasi klien berlangganan nama topik baru (yang belum ada untuk project Firebase Anda), topik baru untuk nama tersebut dibuat di FCM dan setelahnya klien dapat berlangganan.

Untuk berlangganan suatu topik, panggil metode langganan dari thread utama aplikasi Anda (FCM tidak aman untuk thread). Jika awalnya permintaan langganan gagal, FCM akan mencoba kembali secara otomatis. Untuk beberapa kasus yang langganan yang tidak dapat diselesaikan, langganan memunculkan error yang dapat Anda ketahui di pengendali penyelesaian seperti yang ditunjukkan berikut:

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");
}];

Panggilan ini membuat konten asinkron ke backend FCM dan membuat klien berlangganan ke topik tertentu. Sebelum memanggil subscribeToTopic:topic, pastikan bahwa instance aplikasi klien telah menerima token pendaftaran melalui callback didReceiveRegistrationToken.

Setiap kali aplikasi dijalankan, FCM memastikan bahwa aplikasi tersebut telah berlangganan ke semua topik yang diminta. Untuk berhenti berlangganan, panggil unsubscribeFromTopic:topic, dan FCM akan berhenti berlangganan ke topik yang ada di latar belakang.

Menerima dan menangani pesan topik

FCM mengirim pesan topik dengan cara yang sama seperti pesan downstream lainnya.

Menerapkan AppDelegate application:didReceiveRemoteNotification:  seperti yang ditunjukkan berikut:

Swift

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
  // 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)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  // 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)

  completionHandler(UIBackgroundFetchResult.newData)
}

Objective-C

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  // 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 message ID.
  if (userInfo[kGCMMessageIDKey]) {
    NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
  }

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

- (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 message ID.
  if (userInfo[kGCMMessageIDKey]) {
    NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
  }

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

  completionHandler(UIBackgroundFetchResultNewData);
}

Membuat permintaan kirim

Setelah membuat topik, baik dengan membuat instance aplikasi klien berlangganan ke topik di sisi klien atau melalui API server, Anda dapat mengirim pesan ke topik. Dalam logika pengiriman Anda di backend, tentukan nama topik yang diinginkan seperti yang ditunjukkan di bawah ini:

Node.js

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

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

// Send a message to devices subscribed to the provided topic.
admin.messaging().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"
      }
   }
}

Perintah cURL:

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

Untuk mengirim pesan ke kombinasi topik, tentukan kondisi, yang merupakan ekspresi boolean yang menentukan topik target. Misalnya, ketentuan berikut akan mengirim pesan ke perangkat yang berlangganan ke TopicA dan juga TopicB atau TopicC:

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

FCM mengevaluasi terlebih dahulu setiap kondisi di dalam tanda kurung, lalu mengevaluasi ekspresi tersebut dari kiri ke kanan. Pada ekspresi di atas, pengguna yang berlangganan satu topik apa pun tidak akan menerima pesan. Demikian pula, pengguna yang tidak berlangganan ke TopicA tidak akan menerima pesan. Namun, kombinasi berikut menerimanya:

  • TopicA dan TopicB
  • TopicA dan TopicC

Anda dapat menyertakan hingga lima topik dalam ekspresi bersyarat.

Untuk mengirim ke sebuah kondisi:

Node.js

// 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 = {
  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.
admin.messaging().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(new Notification(
        "$GOOG up 1.43% on the day",
        "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day."))
    .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",
    }
  }
}

Perintah cURL:

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

Langkah berikutnya