Check out what’s new from Firebase@ Google I/O 2021, and join our alpha program for early access to the new Remote Config personalization feature. Learn more

Wysyłaj wiadomości do wielu urządzeń w iOS

Firebase Cloud Messaging udostępnia dwa sposoby kierowania wiadomości na wiele urządzeń:

  • Wiadomości tematyczne , które umożliwiają wysyłanie wiadomości do wielu urządzeń, na których włączono określony temat.
  • Wiadomości grupy urządzeń , które umożliwiają wysyłanie pojedynczej wiadomości do wielu wystąpień aplikacji działającej na urządzeniach należących do grupy.

Ten samouczek koncentruje się na wysyłaniu wiadomości tematów z serwera aplikacji przy użyciu pakietu Admin SDK lub interfejsu API REST dla FCM oraz odbieraniu i obsłudze ich w aplikacji na iOS. Na tej stronie wymieniono wszystkie kroki, które należy wykonać, aby to osiągnąć, od konfiguracji po weryfikację — może więc obejmować kroki, które już wykonałeś, jeśli masz skonfigurowaną aplikację kliencką na iOS dla FCM lub wykonałeś kroki, aby wysłać swoją pierwszą wiadomość .

Dodaj Firebase do swojego projektu na iOS

W tej sekcji opisano zadania, które mogłeś wykonać, jeśli masz już włączone inne funkcje Firebase w swojej aplikacji. W przypadku FCM musisz przesłać klucz uwierzytelniania APNs i zarejestrować się, aby otrzymywać powiadomienia zdalne .

Warunki wstępne

  • Zainstaluj następujące elementy:

    • Xcode 12.2 lub nowszy
    • CocoaPods 1.10.0 lub nowszy
  • Upewnij się, że Twój projekt spełnia te wymagania:

    • Twój projekt musi być kierowany na system iOS 10 lub nowszy.
  • Skonfiguruj fizyczne urządzenie z systemem iOS, aby uruchomić aplikację, i wykonaj następujące zadania:

    • Uzyskaj klucz uwierzytelniania Apple Push Notification dla swojego konta Apple Developer .
    • Włącz powiadomienia wypychane w XCode w obszarze App > Capabilities .

Jeśli nie masz jeszcze projektu Xcode i chcesz tylko wypróbować produkt Firebase, możesz pobrać jeden z naszych przykładów szybkiego startu .

Utwórz projekt Firebase

Zanim dodasz Firebase do swojej aplikacji na iOS, musisz utworzyć projekt Firebase, aby połączyć się z aplikacją na iOS. Odwiedź Zrozumienie projektów Firebase, aby dowiedzieć się więcej o projektach Firebase.

Zarejestruj swoją aplikację w Firebase

Gdy masz już projekt Firebase, możesz dodać do niego swoją aplikację na iOS.

Odwiedź stronę Omówienie projektów Firebase, aby dowiedzieć się więcej o sprawdzonych metodach i zagadnieniach dotyczących dodawania aplikacji do projektu Firebase, w tym o tym, jak obsługiwać wiele wariantów kompilacji.

  1. Przejdź do konsoli Firebase .

  2. Na środku strony przeglądu projektu kliknij ikonę iOS ( ), aby uruchomić przepływ pracy instalacji.

    Jeśli dodałeś już aplikację do projektu Firebase, kliknij Dodaj aplikację, aby wyświetlić opcje platformy.

  3. Wpisz identyfikator pakietu swojej aplikacji w polu identyfikator pakietu iOS .

  4. (Opcjonalnie) Wpisz inne informacje o aplikacji: pseudonim aplikacji i identyfikator App Store .

  5. Kliknij Zarejestruj aplikację .

Dodaj plik konfiguracyjny Firebase

  1. Kliknij Pobierz GoogleService-Info.plist, aby uzyskać plik konfiguracyjny GoogleService-Info.plist iOS ( GoogleService-Info.plist ).

  2. Przenieś plik konfiguracyjny do katalogu głównego projektu Xcode. Jeśli pojawi się monit, wybierz, aby dodać plik konfiguracyjny do wszystkich celów.

Jeśli masz w projekcie wiele identyfikatorów pakietów, musisz powiązać każdy identyfikator pakietu z zarejestrowaną aplikacją w konsoli GoogleService-Info.plist aby każda aplikacja mogła mieć własny plik GoogleService-Info.plist .

Dodaj pakiety SDK Firebase do swojej aplikacji

Do instalacji bibliotek Firebase zalecamy użycie CocoaPods . Jeśli jednak wolisz nie używać CocoaPods, możesz bezpośrednio zintegrować frameworki SDK lub zamiast tego użyć Swift Package Manager .

Czy używasz jednej z próbek szybkiego startu ? Projekt Xcode i plik Podfile (z zasobnikami) są już obecne, ale nadal musisz dodać plik konfiguracyjny Firebase i zainstalować zasobniki.

  1. Utwórz plik Podfile, jeśli jeszcze go nie masz:

    cd your-project-directory
    pod init
  2. Do pliku Podfile dodaj bloki Firebase, których chcesz używać w swojej aplikacji.

    Do aplikacji na iOS możesz dodać dowolne obsługiwane produkty Firebase .

    Aby zapewnić optymalne działanie Firebase Cloud Messaging, zalecamy włączenie Google Analytics w swoim projekcie. Ponadto w ramach konfigurowania Analytics musisz dodać do swojej aplikacji pakiet SDK Firebase dla Analytics.

    Analiza włączona

    # Add the Firebase pod for Google Analytics
    pod 'Firebase/Analytics'
    
    # For Analytics without IDFA collection capability, use this pod instead
    # pod ‘Firebase/AnalyticsWithoutAdIdSupport’
    
    # Add the pod for Firebase Cloud Messaging
    pod 'Firebase/Messaging'

    Dowiedz się więcej o IDFA, identyfikatorze reklamowym na poziomie urządzenia, w dokumentacji Apple dotyczącej prywatności użytkowników i wykorzystania danych oraz przejrzystości śledzenia aplikacji .

    Analytics nie jest włączone

    # Add the pod for Firebase Cloud Messaging
    pod 'Firebase/Messaging'
  3. Zainstaluj pody, a następnie otwórz plik .xcworkspace , aby zobaczyć projekt w Xcode:

    pod install
    open your-project.xcworkspace

Prześlij swój klucz uwierzytelniania APNs

Prześlij swój klucz uwierzytelniania APNs do Firebase. Jeśli nie masz jeszcze klucza uwierzytelniania APNs, utwórz go w Apple Developer Member Center .

  1. Wewnątrz projektu w konsoli Firebase wybierz ikonę koła zębatego, wybierz Ustawienia projektu , a następnie wybierz kartę Wiadomości w chmurze .

  2. W kluczu uwierzytelniania APNs w sekcji Konfiguracja aplikacji na iOS kliknij przycisk Prześlij .

  3. Przejdź do lokalizacji, w której zapisano klucz, wybierz go i kliknij Otwórz . Dodaj identyfikator klucza (dostępny w Apple Developer Member Center ) i kliknij Prześlij .

Zainicjuj Firebase w swojej aplikacji

Musisz dodać do aplikacji kod inicjujący Firebase. Zaimportuj moduł Firebase i skonfiguruj udostępnioną instancję, jak pokazano:

  1. Zaimportuj moduł UIApplicationDelegate swojego UIApplicationDelegate :

    Szybki

    import Firebase

    Cel C

    @import Firebase;
  2. Skonfiguruj FirebaseApp wspólne wystąpienie, zazwyczaj w swojej aplikacji application:didFinishLaunchingWithOptions: metodę:

    Szybki

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

    Cel C

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

Zarejestruj się, aby otrzymywać powiadomienia zdalne

Podczas uruchamiania lub w żądanym punkcie przepływu aplikacji zarejestruj aplikację, aby otrzymywać powiadomienia zdalne. registerForRemoteNotifications połączeń dla zdalnych registerForRemoteNotifications jak pokazano:

Szybki

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()

Cel 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];

Subskrybuj aplikację kliencką do tematu

Aplikacje klienckie mogą subskrybować dowolny istniejący temat lub mogą tworzyć nowy temat. Gdy aplikacja kliencka zasubskrybuje nową nazwę tematu (taką, która jeszcze nie istnieje w Twoim projekcie Firebase), nowy temat o tej nazwie jest tworzony w FCM i każdy klient może go następnie subskrybować.

Aby zasubskrybować temat, wywołaj metodę subskrypcji z głównego wątku aplikacji (FCM nie jest bezpieczny wątkowo). Jeśli żądanie subskrypcji początkowo nie powiedzie się, FCM automatycznie ponawia próbę. W przypadkach, w których nie można ukończyć subskrypcji, subskrypcja zgłasza błąd, który można przechwycić w procedurze obsługi ukończenia, jak pokazano:

Szybki

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

Cel C

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

To wywołanie tworzy asynchroniczne żądanie do zaplecza FCM i subskrybuje klienta do danego tematu. Przed wywołaniem subscribeToTopic:topic , upewnij się, że wystąpienie aplikacji klienckiej odebrało już token rejestracji za pośrednictwem wywołania zwrotnego didReceiveRegistrationToken .

Za każdym razem, gdy aplikacja się uruchamia, FCM upewnia się, że wszystkie żądane tematy zostały zasubskrybowane. Aby anulować subskrypcję, wywołaj unsubscribeFromTopic:topic , a FCM anuluje subskrypcję tematu w tle.

Odbieraj i obsługuj wiadomości tematyczne

FCM dostarcza komunikaty tematu w taki sam sposób, jak inne komunikaty podrzędne.

Zaimplementuj application(_:didReceiveRemoteNotification:fetchCompletionHandler:) jak pokazano:

Szybki

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)
}

Cel 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);
}

Zbuduj wyślij żądania

Po utworzeniu tematu, subskrybując wystąpienia aplikacji klienckiej do tematu po stronie klienta lub za pośrednictwem interfejsu API serwera , możesz wysyłać komunikaty do tematu. Jeśli po raz pierwszy budujesz i wysyłasz żądania FCM, zapoznaj się z przewodnikiem po środowisku serwera i FCM, aby uzyskać ważne informacje o tle i konfiguracji.

W logice wysyłania na zapleczu określ żądaną nazwę tematu, jak pokazano:

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.
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);
  });

Jawa

// 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);

Pyton

# 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)

Udać się

// 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)

DO#

// 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);

RESZTA

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, polecenie:

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

Aby wysłać wiadomość do kombinacji tematów, określ warunek , który jest wyrażeniem logicznym określającym tematy docelowe. Na przykład następujący warunek spowoduje wysłanie komunikatów do urządzeń zasubskrybowanych w TopicA i TopicB lub TopicC :

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

FCM najpierw ocenia wszystkie warunki w nawiasach, a następnie ocenia wyrażenie od lewej do prawej. W powyższym wyrażeniu użytkownik zasubskrybowany do dowolnego pojedynczego tematu nie otrzymuje wiadomości. Podobnie użytkownik, który nie subskrybuje TopicA , nie otrzymuje wiadomości. Te kombinacje otrzymują to:

  • TopicA i TopicB
  • TopicA i TopicC

W wyrażeniu warunkowym możesz zawrzeć do pięciu tematów.

Aby wysłać do warunku:

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.
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);
  });

Jawa

// 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);

Pyton

# 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)

Udać się

// 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)

DO#

// 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);

RESZTA

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, polecenie:

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

Następne kroki