Google is committed to advancing racial equity for Black communities. See how.
Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Migrieren Sie Ihre Parse iOS App zu Firebase

Wenn Sie als Parse-Benutzer nach einer alternativen Backend as a Service-Lösung suchen, ist Firebase möglicherweise die ideale Wahl für Ihre iOS-App.

In diesem Handbuch wird beschrieben, wie Sie bestimmte Dienste in Ihre App integrieren. Grundlegende Anweisungen zum Einrichten von Firebase finden Sie im iOS-Setup- Handbuch.

Google Analytics

Google Analytics ist eine kostenlose App-Messlösung, die Einblicke in die App-Nutzung und die Nutzerinteraktion bietet. Analytics ist in alle Firebase-Funktionen integriert und bietet Ihnen unbegrenzte Berichte für bis zu 500 verschiedene Ereignisse, die Sie mit dem Firebase SDK definieren können.

Weitere Informationen finden Sie in den Google Analytics-Dokumenten .

Vorgeschlagene Migrationsstrategie

Die Verwendung verschiedener Analytics-Anbieter ist ein häufiges Szenario, das sich problemlos auf Google Analytics anwenden lässt. Fügen Sie es einfach Ihrer App hinzu, um von Ereignissen und Benutzereigenschaften zu profitieren, die Analytics automatisch erfasst, z. B. Erstes Öffnen, App-Update, Gerätemodell und Alter.

Für benutzerdefinierte Ereignisse und Benutzereigenschaften können Sie eine Doppelschreibstrategie verwenden, bei der sowohl Parse Analytics als auch Google Analytics zum Protokollieren von Ereignissen und Eigenschaften verwendet werden, sodass Sie die neue Lösung schrittweise einführen können.

Codevergleich

Analyse analysieren

 // Start collecting data
[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];

NSDictionary *dimensions = @{
  // Define ranges to bucket data points into meaningful segments
  @"priceRange": @"1000-1500",
  // Did the user filter the query?
  @"source": @"craigslist",
  // Do searches happen more often on weekdays or weekends?
  @"dayType": @"weekday"
};
// Send the dimensions to Parse along with the 'search' event
[PFAnalytics trackEvent:@"search" dimensions:dimensions];
 

Google Analytics

 // Obtain the AppMeasurement instance and start collecting data
[FIRApp configure];

// Send the event with your params
[FIRAnalytics logEventWithName:@"search" parameters:@{
  // Define ranges to bucket data points into meaningful segments
  @"priceRange": @"1000-1500",
  // Did the user filter the query?
  @"source": @"craigslist",
  // Do searches happen more often on weekdays or weekends?
  @"dayType": @"weekday"
}];
 

Firebase-Echtzeitdatenbank

Die Firebase-Echtzeitdatenbank ist eine in der NoSQL-Cloud gehostete Datenbank. Die Daten werden als JSON gespeichert und in Echtzeit mit jedem verbundenen Client synchronisiert.

Weitere Informationen finden Sie in den Firebase Realtime Database-Dokumenten .

Unterschiede zu Analysedaten

Objekte

In Parse speichern Sie ein PFObject oder eine Unterklasse davon, die Schlüssel-Wert-Paare von JSON-kompatiblen Daten enthält. Die Daten sind schemenlos, dh Sie müssen nicht angeben, welche Schlüssel auf jedem PFObject .

Alle Firebase-Echtzeitdatenbankdaten werden als JSON-Objekte gespeichert, und es gibt kein Äquivalent für PFObject . Sie schreiben einfach in die JSON-Baumwerte Werte von Typen, die den verfügbaren JSON-Typen entsprechen.

Das Folgende ist ein Beispiel dafür, wie Sie die Highscores für ein Spiel speichern können.

Analysieren
 PFObject *gameScore = [PFObject objectWithClassName:@"GameScore"];
gameScore[@"score"] = @1337;
gameScore[@"playerName"] = @"Sean Plott";
gameScore[@"cheatMode"] = @NO;
[gameScore saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
  if (succeeded) {
    // The object has been saved.
  } else {
    // There was a problem, check error.description
  }
}];
 
Feuerbasis
 // Create a reference to the database
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
NSString *key = [[ref child:@"scores"] childByAutoId].key;
NSDictionary *score = @{@"score": @1337,
                        @"playerName": @"Sean Plott",
                        @"cheatMode": @NO};
[key setValue:score withCompletionBlock:^(NSError *error,  FIRDatabaseReference *ref) {
  if (error) {
    // The object has been saved.
  } else {
    // There was a problem, check error.description
  }
}];
 
Weitere Informationen finden Sie im Handbuch Lesen und Schreiben von Daten unter iOS .

Beziehungen zwischen Daten

Ein PFObject kann eine Beziehung zu einem anderen PFObject : PFObject Objekt kann andere Objekte als Werte verwenden.

In der Firebase-Echtzeitdatenbank werden Beziehungen besser durch flache Datenstrukturen ausgedrückt, die die Daten in separate Pfade aufteilen, sodass sie in separaten Aufrufen effizient heruntergeladen werden können.

Das folgende Beispiel zeigt, wie Sie die Beziehung zwischen Posts in einer Blogging-App und ihren Autoren strukturieren können.

Analysieren
 // Create the author
PFObject *myAuthor = [PFObject objectWithClassName:@"Author"];
myAuthor[@"name"] = @"Grace Hopper";
myAuthor[@"birthDate"] = @"December 9, 1906";
myAuthor[@"nickname"] = @"Amazing Grace";

// Create the post
PFObject *myPost = [PFObject objectWithClassName:@"Post"];
myPost[@"title"] = @"Announcing COBOL, a New Programming Language";

// Add a relation between the Post and the Author
myPost[@"parent"] = myAuthor;

// This will save both myAuthor and myPost
[myPost saveInBackground];
 
Feuerbasis
 // Create a reference to the database
FIRDatabaseReference *ref = [[FIRDatabase database] reference];

// Create the author
NSString *myAuthorKey = @"ghopper";
NSDictionary *author = @{@"name": @"Grace Hopper",
                         @"birthDate": @"December 9, 1906",
                         @"nickname": @"Amazing Grace"};
// Save the author
[[ref child:myAuthorKey] setValue:author]

// Create and save the post
NSString *key = [[ref child:@"posts"] childByAutoId].key;
NSDictionary *post = @{@"author": myAuthorKey,
                       @"title": @"Announcing COBOL, a New Programming Language"};
[key setValue:post]
 

Das folgende Datenlayout ist das Ergebnis.

{
  // Info about the authors
  "authors": {
    "ghopper": {
      "name": "Grace Hopper",
      "date_of_birth": "December 9, 1906",
      "nickname": "Amazing Grace"
    },
    ...
  },
  // Info about the posts: the "author" fields contains the key for the author
  "posts": {
    "-JRHTHaIs-jNPLXOQivY": {
      "author": "ghopper",
      "title": "Announcing COBOL, a New Programming Language"
    }
    ...
  }
}
Weitere Informationen finden Sie im Handbuch Strukturieren Ihrer Datenbank .

Daten lesen

In Parse lesen Sie Daten entweder mit der ID eines bestimmten Parse-Objekts oder führen Abfragen mit PFQuery .

In Firebase rufen Sie Daten ab, indem Sie einen asynchronen Listener an eine Datenbankreferenz anhängen. Der Listener wird einmal für den Anfangszustand der Daten und erneut ausgelöst, wenn sich die Daten ändern, sodass Sie keinen Code hinzufügen müssen, um festzustellen, ob sich die Daten geändert haben.

Das Folgende ist ein Beispiel dafür, wie Sie Punkte für einen bestimmten Spieler abrufen können, basierend auf dem Beispiel im Abschnitt "Objekte" .

Analysieren
 PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
[query whereKey:@"playerName" equalTo:@"Dan Stemkoski"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
  if (!error) {
    for (PFObject *score in objects) {
      NSString *gameScore = score[@"score"];
      NSLog(@"Retrieved: %@", gameScore);
    }
  } else {
    // Log details of the failure
    NSLog(@"Error: %@ %@", error, [error userInfo]);
  }
}];
 
Feuerbasis
 // Create a reference to the database
FIRDatabaseReference *ref = [[FIRDatabase database] reference];

// This type of listener is not one time, and you need to cancel it to stop
// receiving updates.
[[[[ref child:@"scores"] queryOrderedByChild:@"playerName"] queryEqualToValue:@"Dan Stemkoski"]
    observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot *snapshot) {
  // This will fire for each matching child node.
  NSDictionary *score = snapshot.value;
  NSString gameScore = score[@"score"];
  NSLog(@"Retrieved: %@", gameScore);
}];
 
Weitere Informationen zu verfügbaren Arten von Ereignis-Listenern sowie zum Bestellen und Filtern von Daten finden Sie im Handbuch Lesen und Schreiben von Daten unter iOS .

Vorgeschlagene Migrationsstrategie

Überdenken Sie Ihre Daten

Die Firebase-Echtzeitdatenbank ist so optimiert, dass Daten in Millisekunden über alle verbundenen Clients hinweg synchronisiert werden. Die resultierende Datenstruktur unterscheidet sich von den Parse-Kerndaten. Dies bedeutet, dass der erste Schritt Ihrer Migration darin besteht, zu prüfen, welche Änderungen Ihre Daten erfordern, einschließlich:

  • Wie Ihre Parse-Objekte Firebase-Daten zugeordnet werden sollen
  • Wenn Sie Eltern-Kind-Beziehungen haben, wie Sie Ihre Daten auf verschiedene Pfade aufteilen, damit sie in separaten Aufrufen effizient heruntergeladen werden können.

Migrieren Sie Ihre Daten

Nachdem Sie entschieden haben, wie Ihre Daten in Firebase strukturiert werden sollen, müssen Sie planen, wie der Zeitraum behandelt werden soll, in dem Ihre App in beide Datenbanken schreiben muss. Sie haben folgende Möglichkeiten:

Hintergrundsynchronisation

In diesem Szenario haben Sie zwei Versionen der App: die alte Version, die Parse verwendet, und eine neue Version, die Firebase verwendet. Synchronisierungen zwischen den beiden Datenbanken werden von Parse Cloud Code (Parse to Firebase) durchgeführt, wobei Ihr Code Änderungen in Firebase abhört und diese Änderungen mit Parse synchronisiert. Bevor Sie die neue Version verwenden können, müssen Sie:

  • Konvertieren Sie Ihre vorhandenen Analysedaten in die neue Firebase-Struktur und schreiben Sie sie in die Firebase-Echtzeitdatenbank.
  • Schreiben Sie Parse Cloud Code-Funktionen, die die Firebase REST-API verwenden, um Änderungen in die Firebase Realtime Database zu schreiben, die von alten Clients in den Parse Data vorgenommen wurden.
  • Schreiben und Bereitstellen von Code, der Änderungen in Firebase abhört und mit der Parse-Datenbank synchronisiert.

Dieses Szenario gewährleistet eine saubere Trennung von altem und neuem Code und hält die Clients einfach. Die Herausforderungen dieses Szenarios bestehen darin, große Datenmengen beim ersten Export zu verarbeiten und sicherzustellen, dass die bidirektionale Synchronisierung keine unendliche Rekursion erzeugt.

Double Write

In diesem Szenario schreiben Sie eine neue Version der App, die sowohl Firebase als auch Parse verwendet, und verwenden Parse Cloud Code, um Änderungen, die von alten Clients vorgenommen wurden, von den Parse-Daten in die Firebase-Echtzeitdatenbank zu synchronisieren. Wenn genügend Personen von der Nur-Analyse-Version der App migriert sind, können Sie den Analyse-Code aus der Double-Write-Version entfernen.

Dieses Szenario erfordert keinen serverseitigen Code. Die Nachteile sind, dass Daten, auf die nicht zugegriffen wird, nicht migriert werden und dass die Größe Ihrer App durch die Verwendung beider SDKs erhöht wird.

Firebase-Authentifizierung

Mit der Firebase-Authentifizierung können Benutzer mithilfe von Kennwörtern und beliebten Verbundidentitätsanbietern wie Google, Facebook und Twitter authentifiziert werden. Darüber hinaus werden UI-Bibliotheken bereitgestellt, mit denen Sie die erheblichen Investitionen sparen, die für die Implementierung und Aufrechterhaltung einer vollständigen Authentifizierungserfahrung für Ihre App auf allen Plattformen erforderlich sind.

Weitere Informationen finden Sie in den Firebase-Authentifizierungsdokumenten .

Unterschiede mit Parse Auth

Parse bietet eine spezielle Benutzerklasse namens PFUser , die automatisch die für die Verwaltung von Benutzerkonten erforderlichen Funktionen verwaltet. PFUser ist eine Unterklasse des PFObject bedeutet, dass Benutzerdaten in den Analysedaten verfügbar sind und wie jedes andere PFObject um zusätzliche Felder erweitert werden PFObject .

Ein FIRUser verfügt über einen festen Satz grundlegender Eigenschaften - eine eindeutige ID, eine primäre E-Mail-Adresse, einen Namen und eine Foto-URL -, die in der Benutzerdatenbank eines separaten Projekts gespeichert sind. Diese Eigenschaften können vom Benutzer aktualisiert werden. Sie können dem FIRUser Objekt keine anderen Eigenschaften direkt hinzufügen. Stattdessen können Sie die zusätzlichen Eigenschaften in Ihrer Firebase-Echtzeitdatenbank speichern.

Das folgende Beispiel zeigt, wie Sie einen Benutzer anmelden und ein zusätzliches Telefonnummernfeld hinzufügen können.

Analysieren
 PFUser *user = [PFUser user];
user.username = @"my name";
user.password = @"my pass";
user.email = @"email@example.com";

// other fields can be set just like with PFObject
user[@"phone"] = @"415-392-0202";

[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
  if (!error) {
    // Hooray! Let them use the app now.
  } else {
    // Something went wrong
    NSString *errorString = [error userInfo][@"error"];
  }
}];
 
Feuerbasis
 [[FIRAuth auth] createUserWithEmail:@"email@example.com"
                           password:@"my pass"
                         completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
  if (!error) {
    FIRDatabaseReference *ref = [[FIRDatabase database] reference];
    [[[[ref child:@"users"] child:user.uid] child:@"phone"] setValue:@"415-392-0202"
  } else {
    // Something went wrong
    NSString *errorString = [error userInfo][@"error"];
  }
}];
 

Vorgeschlagene Migrationsstrategie

Konten migrieren

Um Benutzerkonten von Parse nach Firebase zu migrieren, exportieren Sie Ihre Benutzerdatenbank in eine JSON- oder CSV-Datei und importieren Sie die Datei dann mit dem Befehl auth:import der Firebase-CLI in Ihr Firebase-Projekt.

Exportieren Sie zunächst Ihre Benutzerdatenbank von der Parse-Konsole oder Ihrer selbst gehosteten Datenbank. Beispielsweise könnte eine aus der Parse-Konsole exportierte JSON-Datei folgendermaßen aussehen:

{ // Username/password user
  "bcryptPassword": "$2a$10$OBp2hxB7TaYZgKyTiY48luawlTuYAU6BqzxJfpHoJMdZmjaF4HFh6",
  "email": "user@example.com",
  "username": "testuser",
  "objectId": "abcde1234",
  ...
},
{ // Facebook user
  "authData": {
    "facebook": {
      "access_token": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
      "expiration_date": "2017-01-02T03:04:05.006Z",
      "id": "1000000000"
    }
  },
  "username": "wXyZ987654321StUv",
  "objectId": "fghij5678",
  ...
}

Transformieren Sie dann die exportierte Datei in das von der Firebase-CLI erforderliche Format. Verwenden Sie die objectId Ihrer Parse-Benutzer als localId Ihrer Firebase-Benutzer. Außerdem codiert base64 die bcryptPassword Werte von Parse und verwendet sie im Feld passwordHash . Beispielsweise:

{
  "users": [
    {
      "localId": "abcde1234",  // Parse objectId
      "email": "user@example.com",
      "displayName": "testuser",
      "passwordHash": "JDJhJDEwJE9CcDJoeEI3VGFZWmdLeVRpWTQ4bHVhd2xUdVlBVTZCcXp4SmZwSG9KTWRabWphRjRIRmg2",
    },
    {
      "localId": "fghij5678",  // Parse objectId
      "displayName": "wXyZ987654321StUv",
      "providerUserInfo": [
        {
          "providerId": "facebook.com",
          "rawId": "1000000000",  // Facebook ID
        }
      ]
    }
  ]
}

Importieren Sie abschließend die transformierte Datei mit der Firebase-CLI und geben Sie bcrypt als Hash-Algorithmus an:

firebase auth:import account_file.json --hash-algo=BCRYPT

Benutzerdaten migrieren

Wenn Sie zusätzliche Daten für Ihre Benutzer speichern, können Sie diese mithilfe der im Abschnitt Datenmigration beschriebenen Strategien in die Firebase-Echtzeitdatenbank migrieren. Wenn Sie wandern Konten den Fluss in der beschriebenen Konten Migration Abschnitt, Ihre Konten Firebase die gleichen IDs Ihrer Parse haben Konten, so dass Sie leicht migrieren und alle Beziehungen durch den Benutzer - ID eingegeben zu reproduzieren.

Firebase Cloud Messaging

Firebase Cloud Messaging (FCM) ist eine plattformübergreifende Messaging-Lösung, mit der Sie Nachrichten und Benachrichtigungen zuverlässig und kostenlos übermitteln können. Der Notifications Composer ist ein kostenloser Dienst, der auf Firebase Cloud Messaging basiert und gezielte Benutzerbenachrichtigungen für Entwickler mobiler Apps ermöglicht.

Weitere Informationen finden Sie in den Firebase Cloud Messaging-Dokumenten .

Unterschiede bei Parse Push-Benachrichtigungen

Jeder Parse-Anwendung, die auf einem für Benachrichtigungen registrierten Gerät installiert ist, ist ein Installation , in dem Sie alle Daten speichern, die für die Ausrichtung auf Benachrichtigungen erforderlich sind. Installation ist eine Unterklasse von PFUser bedeutet, dass Sie Ihren Installation beliebige zusätzliche Daten hinzufügen können.

Der Notifications Composer bietet vordefinierte Benutzersegmente basierend auf Informationen wie App, App-Version und Gerätesprache. Mithilfe von Google Analytics-Ereignissen und -Eigenschaften können Sie komplexere Benutzersegmente erstellen, um Zielgruppen zu erstellen. Weitere Informationen finden Sie in der Zielgruppenhilfe . Diese Targeting-Informationen sind in der Firebase-Echtzeitdatenbank nicht sichtbar.

Vorgeschlagene Migrationsstrategie

Gerätetoken migrieren

Während Parse APNs-Gerätetoken verwendet, um Installationen für Benachrichtigungen auszurichten, verwendet FCM FCM-Registrierungstoken, die den APNs-Gerätetoken zugeordnet sind. Fügen Sie einfach das FCM SDK zu Ihrer iOS-App hinzu und es wird automatisch ein FCM-Token abgerufen .

Migrieren von Kanälen zu FCM-Themen

Wenn Sie zum Senden von Benachrichtigungen Parse-Kanäle verwenden, können Sie zu FCM-Themen migrieren, die dasselbe Publisher-Subscriber-Modell bereitstellen. Um den Übergang von Parse zu FCM zu handhaben, können Sie eine neue Version der App schreiben, die das Parse SDK zum Abbestellen von Parse-Kanälen und das FCM SDK zum Abonnieren entsprechender FCM-Themen verwendet.

Wenn Ihr Benutzer beispielsweise das Thema "Riesen" abonniert hat, würden Sie Folgendes tun:

 PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation removeObject:@"Giants" forKey:@"channels"];
[currentInstallation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
  if (succedeed) {
    [[FIRMessaging messaging] subscribeToTopic:@"/topics/Giants"];
  } else {
    // Something went wrong unsubscribing
  }
}];
 

Mit dieser Strategie können Sie Nachrichten sowohl an den Analysekanal als auch an das entsprechende FCM-Thema senden und Benutzer sowohl alter als auch neuer Versionen unterstützen. Wenn genügend Benutzer von der Nur-Analyse-Version der App migriert sind, können Sie diese Version beenden und nur mit FCM senden.

Weitere Informationen finden Sie in den Dokumenten zu FCM-Themen .

Firebase Remote Config

Firebase Remote Config ist ein Cloud-Dienst, mit dem Sie das Verhalten und das Erscheinungsbild Ihrer App ändern können, ohne dass Benutzer ein App-Update herunterladen müssen. Bei Verwendung von Remote Config erstellen Sie In-App-Standardwerte, die das Verhalten und das Erscheinungsbild Ihrer App steuern. Anschließend können Sie später die Firebase-Konsole verwenden, um In-App-Standardwerte für alle App-Benutzer oder für Segmente Ihrer Benutzerbasis zu überschreiben.

Firebase Remote Config kann während Ihrer Migrationen sehr nützlich sein, wenn Sie verschiedene Lösungen testen und mehr Clients dynamisch zu einem anderen Anbieter verschieben möchten. Wenn Sie beispielsweise eine Version Ihrer App haben, die sowohl Firebase als auch Parse für die Daten verwendet, können Sie mithilfe einer zufälligen Perzentilregel bestimmen, welche Clients aus Firebase lesen, und den Prozentsatz schrittweise erhöhen.

Weitere Informationen zu Firebase Remote Config finden Sie in der Einführung zu Remote Config .

Unterschiede mit Parse Config

Mit Parse config können Sie Ihrer App im Parse Config Dashboard Schlüssel / Wert-Paare hinzufügen und dann die PFConfig auf dem Client PFConfig . Jede PFConfig Instanz, die Sie erhalten, ist immer unveränderlich. Wenn Sie in Zukunft eine neue PFConfig aus dem Netzwerk PFConfig , wird keine vorhandene PFConfig Instanz PFConfig , sondern eine neue erstellt und über currentConfig verfügbar gemacht.

Mit Firebase Remote Config erstellen Sie In-App-Standardeinstellungen für Schlüssel / Wert-Paare, die Sie über die Firebase-Konsole überschreiben können, und Sie können Regeln und Bedingungen verwenden, um Variationen der Benutzererfahrung Ihrer App für verschiedene Segmente Ihrer Benutzerbasis bereitzustellen. Firebase Remote Config implementiert eine Singleton-Klasse, die die Schlüssel / Wert-Paare für Ihre App verfügbar macht. Zunächst gibt der Singleton die Standardwerte zurück, die Sie in der App definieren. Sie können jederzeit einen neuen Wertesatz vom Server abrufen, der für Ihre App günstig ist. Nachdem der neue Satz erfolgreich abgerufen wurde, können Sie auswählen, wann er aktiviert werden soll, um die neuen Werte für die App verfügbar zu machen.

Vorgeschlagene Migrationsstrategie

Sie können zu Firebase Remote Config wechseln, indem Sie die Schlüssel / Wert-Paare Ihrer Parse-Konfiguration auf die Firebase-Konsole kopieren und anschließend eine neue Version der App bereitstellen, die Firebase Remote Config verwendet.

Wenn Sie sowohl mit Parse Config als auch mit Firebase Remote Config experimentieren möchten, können Sie eine neue Version der App bereitstellen, die beide SDKs verwendet, bis genügend Benutzer von der Nur-Parse-Version migriert sind.

Codevergleich

Analysieren

 [PFConfig getConfigInBackgroundWithBlock:^(PFConfig *config, NSError *error) {
  if (!error) {
    NSLog(@"Yay! Config was fetched from the server.");
  } else {
    NSLog(@"Failed to fetch. Using Cached Config.");
    config = [PFConfig currentConfig];
  }

  NSString *welcomeMessage = config[@"welcomeMessage"];
  if (!welcomeMessage) {
    NSLog(@"Falling back to default message.");
    welcomeMessage = @"Welcome!";
  }
}];
 

Feuerbasis

 FIRRemoteConfig remoteConfig = [FIRRemoteConfig remoteConfig];
// Set defaults from a plist file
[remoteConfig setDefaultsFromPlistFileName:@"RemoteConfigDefaults"];

[remoteConfig fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) {
  if (status == FIRRemoteConfigFetchStatusSuccess) {
    NSLog(@"Yay! Config was fetched from the server.");
    // Once the config is successfully fetched it must be activated before newly fetched
    // values are returned.
    [self.remoteConfig activateFetched];
  } else {
    NSLog(@"Failed to fetch. Using last fetched or default.");
  }
}];

// ...

// When this is called, the value of the latest fetched and activated config is returned;
// if there's none, the default value is returned.
NSString welcomeMessage = remoteConfig[@"welcomeMessage"].stringValue;