Wysyłaj wiadomości do wielu urządzeń na platformach Apple

Aby kierować wiadomość do wielu urządzeń, użyj Wiadomości tematycznych . Ta funkcja umożliwia wysłanie wiadomości do wielu urządzeń, które wybrały określony temat.

W tym samouczku skupiono się na wysyłaniu komunikatów tematycznych z serwera aplikacji przy użyciu pakietu Admin SDK lub interfejsu API REST dla FCM oraz odbieraniu ich i obsłudze w aplikacji Apple. Na tej stronie znajdują się 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 skonfigurowałeś aplikację kliencką Apple dla FCM lub wykonałeś kroki wysyłania pierwszej wiadomości .

Dodaj Firebase do swojego projektu Apple

W tej sekcji omówiono zadania, które mogłeś wykonać, jeśli włączyłeś już inne funkcje Firebase w swojej aplikacji. W szczególności w przypadku FCM musisz przesłać klucz uwierzytelniający APNs i zarejestrować się, aby otrzymywać zdalne powiadomienia .

Warunki wstępne

  • Zainstaluj następujące elementy:

    • Xcode 14.1 lub nowszy
  • Upewnij się, że Twój projekt spełnia następujące wymagania:

    • Twój projekt musi być przeznaczony dla tych wersji platform lub nowszych:
      • iOS 11
      • macOS 10.13
      • tvOS 12
      • zegarekOS 6
  • Skonfiguruj fizyczne urządzenie Apple do uruchamiania aplikacji i wykonaj następujące zadania:

    • Uzyskaj klucz uwierzytelniający powiadomienia Apple Push dla swojego konta programisty Apple .
    • Włącz powiadomienia push w XCode w obszarze Aplikacja > Możliwości .

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

Utwórz projekt Firebase

Zanim będziesz mógł dodać Firebase do swojej aplikacji Apple, musisz utworzyć projekt Firebase, aby połączyć się z Twoją aplikacją. Odwiedź stronę Poznaj projekty Firebase, aby dowiedzieć się więcej o projektach Firebase.

Zarejestruj swoją aplikację w Firebase

Aby używać Firebase w aplikacji Apple, musisz zarejestrować aplikację w projekcie Firebase. Rejestracja aplikacji jest często nazywana „dodawaniem” aplikacji do projektu.

  1. Przejdź do konsoli Firebase .

  2. Na środku strony przeglądu projektu kliknij ikonę iOS+ , aby uruchomić proces konfiguracji.

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

  3. Wpisz identyfikator pakietu aplikacji w polu identyfikatora pakietu .

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

  5. Kliknij opcję Zarejestruj aplikację .

Dodaj plik konfiguracyjny Firebase

  1. Kliknij opcję Pobierz GoogleService-Info.plist , aby uzyskać plik konfiguracyjny platform Firebase Apple ( GoogleService-Info.plist ).

  2. Przenieś plik konfiguracyjny do katalogu głównego projektu Xcode. Jeśli zostanie wyświetlony monit, wybierz opcję dodania pliku konfiguracyjnego do wszystkich obiektów docelowych.

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

Dodaj pakiety SDK Firebase do swojej aplikacji

Użyj Menedżera pakietów Swift, aby zainstalować zależności Firebase i zarządzać nimi.

  1. W Xcode, przy otwartym projekcie aplikacji, przejdź do File > Add Packages .
  2. Po wyświetleniu monitu dodaj repozytorium SDK platform Firebase Apple:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Wybierz bibliotekę Firebase Cloud Messaging.
  5. Dodaj flagę -ObjC do sekcji Inne flagi linkera w ustawieniach kompilacji celu.
  6. Aby zapewnić optymalne działanie Firebase Cloud Messaging, zalecamy włączenie Google Analytics w projekcie Firebase i dodanie pakietu SDK Firebase dla Google Analytics do swojej aplikacji. Można wybrać bibliotekę bez kolekcji IDFA lub z kolekcją IDFA.
  7. Po zakończeniu Xcode automatycznie rozpocznie rozwiązywanie i pobieranie zależności w tle.

Prześlij swój klucz uwierzytelniający APNs

Prześlij swój klucz uwierzytelniający APNs do Firebase. Jeśli nie masz jeszcze klucza uwierzytelniającego APNs, pamiętaj o utworzeniu 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ę Cloud Messaging .

  2. W kluczu uwierzytelniania APN w obszarze konfiguracji aplikacji na iOS kliknij przycisk Prześlij .

  3. Przejdź do lokalizacji, w której zapisałeś 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ć kod inicjujący Firebase do swojej aplikacji. Zaimportuj moduł Firebase i skonfiguruj instancję współdzieloną, jak pokazano:

  1. Zaimportuj moduł FirebaseCore do swojego UIApplicationDelegate , a także wszelkie inne moduły Firebase, których używa delegat aplikacji. Na przykład, aby użyć Cloud Firestore i uwierzytelniania:

    SwiftUI

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

    Szybki

    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Cel C

    @import FirebaseCore;
    @import FirebaseFirestore;
    @import FirebaseAuth;
    // ...
          
  2. Skonfiguruj udostępnioną instancję FirebaseApp w aplikacji delegata application(_:didFinishLaunchingWithOptions:) metoda:

    SwiftUI

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

    Szybki

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

    Cel C

    // Use Firebase library to configure APIs
    [FIRApp configure];
  3. Jeśli używasz SwiftUI, musisz utworzyć delegata aplikacji i dołączyć go do struktury App za pośrednictwem UIApplicationDelegateAdaptor lub NSApplicationDelegateAdaptor . Musisz także wyłączyć przełączanie delegatów aplikacji. Aby uzyskać więcej informacji, zapoznaj się z instrukcjami SwiftUI .

    SwiftUI

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

Zarejestruj się, aby otrzymywać zdalne powiadomienia

Zarejestruj aplikację przy uruchamianiu lub w żądanym momencie przepływu aplikacji, aby otrzymywać zdalne powiadomienia. Zadzwoń do registerForRemoteNotifications , jak pokazano:

Szybki


UNUserNotificationCenter.current().delegate = self

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

application.registerForRemoteNotifications()

Cel C


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

[application registerForRemoteNotifications];

Subskrybuj aplikację kliencką do tematu

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

Aby zasubskrybować temat, wywołaj metodę subskrypcji z głównego wątku aplikacji (FCM nie jest bezpieczny dla wątków). Jeśli żądanie subskrypcji początkowo nie powiedzie się, FCM automatycznie ponawia próbę. W przypadkach, gdy subskrypcja nie może zostać ukończona, subskrypcja zgłasza błąd, który można przechwycić w procedurze obsługi zakoń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 wysyła asynchroniczne żądanie do backendu FCM i subskrybuje klienta do danego tematu. Przed wywołaniem subscribeToTopic:topic upewnij się, że instancja aplikacji klienckiej otrzymała już token rejestracji za pośrednictwem wywołania zwrotnego didReceiveRegistrationToken .

Przy każdym uruchomieniu aplikacji FCM sprawdza, czy wszystkie żądane tematy zostały subskrybowane. Aby zrezygnować z subskrypcji, wywołaj unsubscribeFromTopic:topic , a FCM anuluje subskrypcję tematu w tle.

Odbieraj i obsługuj wiadomości tematyczne

FCM dostarcza wiadomości tematyczne w taki sam sposób, jak inne wiadomości niższego szczebla.

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

Szybki

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
}

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

Twórz żądania wysyłania

Po utworzeniu tematu, subskrybując instancje aplikacji klienckiej do tematu po stronie klienta lub za pośrednictwem interfejsu API serwera , możesz wysyłać wiadomości do tematu. Jeśli tworzysz żądania wysyłania dla FCM po raz pierwszy, zapoznaj się z przewodnikiem po środowisku serwera i FCM , aby uzyskać ważne informacje dotyczące tła 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.
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);
  });

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)

Iść

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

ODPOCZYNEK

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

polecenie 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

Aby wysłać wiadomość do kombinacji tematów, określ warunek , który jest wyrażeniem boolowskim określającym tematy docelowe. Na przykład następujący warunek wyśle ​​wiadomości do urządzeń subskrybujących TopicA oraz 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 subskrybujący dowolny temat nie otrzymuje wiadomości. Podobnie użytkownik, który nie subskrybuje TopicA nie otrzyma wiadomości. Te kombinacje go otrzymują:

  • TopicA i TopicB
  • TopicA i TopicC

W wyrażeniu warunkowym możesz uwzględnić maksymalnie pięć 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.
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);
  });

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)

Iść

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

ODPOCZYNEK

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",
    }
  }
}

polecenie 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

Następne kroki