Firebase iOS Codelab Swift

1. Übersicht

2efe6805ef369641.png

Willkommen beim Codelab „Friendly Chat“. In diesem Codelab erfahren Sie, wie Sie mit der Firebase-Plattform iOS-Anwendungen erstellen. Sie implementieren einen Chatclient und überwachen seine Leistung mit Firebase.

Lerninhalte

  • Nutzern die Anmeldung erlauben
  • Synchronisieren von Daten mithilfe der Firebase Realtime Database.
  • Binärdateien in Firebase Storage speichern

Voraussetzungen

  • Xcode
  • CocoaPods
  • Ein Testgerät mit iOS 8.0 oder höher oder ein Simulator

Wie werden Sie diese Anleitung verwenden?

Nur lesen Lesen und Übungen durchführen

Wie würden Sie Ihre Erfahrung mit der Entwicklung von iOS-Apps bewerten?

Anfänger Mittelstufe Fortgeschritten

2. Beispielcode abrufen

Klonen Sie das GitHub-Repository über die Befehlszeile.

$ git clone https://github.com/firebase/codelab-friendlychat-ios

3. Start-App erstellen

2f4c98d858c453fe.png

So erstellen Sie die Start-App:

  1. Wechseln Sie in einem Terminalfenster zum Verzeichnis android_studio_folder.pngios-starter/swift-starter aus dem heruntergeladenen Beispielcode.
  2. Führen Sie pod install --repo-update aus
  3. Öffnen Sie die Datei „FriendlyChatSwift.xcworkspace“, um das Projekt in Xcode zu öffnen.
  4. Klicken Sie auf die Schaltfläche 98205811bbed9d74.pngAusführen.

Nach einigen Sekunden sollte der Startbildschirm von Friendly Chat angezeigt werden. Die Benutzeroberfläche sollte angezeigt werden. Sie können sich jedoch nicht anmelden und keine Nachrichten senden oder empfangen. Die App wird mit einer Ausnahme abgebrochen, bis Sie den nächsten Schritt abgeschlossen haben.

4. Firebase-Projekt einrichten

Neues Firebase-Projekt erstellen

  1. Melden Sie sich mit Ihrem Google-Konto in der Firebase Console an.
  2. Klicken Sie auf die Schaltfläche, um ein neues Projekt zu erstellen, und geben Sie dann einen Projektnamen ein (z. B. FriendlyChat).
  3. Klicken Sie auf Weiter.
  4. Lesen und akzeptieren Sie bei Aufforderung die Firebase-Nutzungsbedingungen und klicken Sie dann auf Weiter.
  5. (Optional) Aktivieren Sie die KI-Unterstützung in der Firebase Console (als „Gemini in Firebase“ bezeichnet).
  6. Für dieses Codelab benötigen Sie kein Google Analytics. Deaktivieren Sie daher die Google Analytics-Option.
  7. Klicken Sie auf Projekt erstellen, warten Sie, bis Ihr Projekt bereitgestellt wurde, und klicken Sie dann auf Weiter.

Firebase-Tarif upgraden

Wenn Sie Cloud Storage for Firebase verwenden möchten, muss für Ihr Firebase-Projekt der Blaze-Tarif (Pay as you go) aktiviert sein. Das bedeutet, dass es mit einem Cloud-Rechnungskonto verknüpft ist.

  • Für ein Cloud-Rechnungskonto ist eine Zahlungsmethode wie eine Kreditkarte erforderlich.
  • Wenn Sie neu bei Firebase und Google Cloud sind, können Sie prüfen, ob Sie Anspruch auf ein Guthaben von 300$und ein Cloud-Rechnungskonto für den kostenlosen Testzeitraum haben.
  • Wenn Sie dieses Codelab im Rahmen einer Veranstaltung durchführen, fragen Sie den Organisator, ob Cloud-Guthaben verfügbar ist.

So führen Sie für Ihr Projekt ein Upgrade auf den Tarif „Blaze“ durch:

  1. Wählen Sie in der Firebase Console die Option zum Upgraden Ihres Abos aus.
  2. Wählen Sie den Blaze-Tarif aus. Folgen Sie der Anleitung auf dem Bildschirm, um ein Cloud-Rechnungskonto mit Ihrem Projekt zu verknüpfen.
    Wenn Sie im Rahmen dieses Upgrades ein Cloud-Rechnungskonto erstellen mussten, müssen Sie möglicherweise zur Firebase-Konsole zurückkehren, um das Upgrade abzuschließen.

iOS-App verbinden

  1. Klicken Sie auf der Übersichtsseite Ihres neuen Projekts auf Firebase zu meiner iOS-App hinzufügen.
  2. Geben Sie die Bundle-ID als „com.google.firebase.codelab.FriendlyChatSwift“ ein.
  3. Geben Sie die App Store-ID als „123456“ ein.
  4. Klicken Sie auf App registrieren.

Datei „GoogleService-Info.plist“ zur App hinzufügen

Klicken Sie auf dem zweiten Bildschirm auf GoogleService-Info.plist herunterladen, um eine Konfigurationsdatei herunterzuladen, die alle erforderlichen Firebase-Metadaten für Ihre App enthält. Kopieren Sie diese Datei in Ihre Anwendung und fügen Sie sie dem Ziel FriendlyChatSwift hinzu.

Sie können jetzt oben rechts im Pop-up-Fenster auf das „x“ klicken, um es zu schließen. Die Schritte 3 und 4 werden hier ausgeführt.

19d59efb213ddbdc.png

Firebase-Modul importieren

Prüfen Sie zuerst, ob das Modul Firebase importiert wurde.

AppDelegate.swift, FCViewController.swift

import Firebase

Firebase in AppDelegate konfigurieren

Verwenden Sie die Methode „configure“ in FirebaseApp innerhalb der Funktion „application:didFinishLaunchingWithOptions“, um zugrunde liegende Firebase-Dienste aus Ihrer PLIST-Datei zu konfigurieren.

AppDelegate.swift

  func application(_ application: UIApplication, didFinishLaunchingWithOptions
      launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  FirebaseApp.configure()
  GIDSignIn.sharedInstance().delegate = self
  return true
}

5. Nutzer identifizieren

Regeln verwenden, um den Zugriff auf authentifizierte Nutzer zu beschränken

Wir fügen jetzt eine Regel hinzu, die eine Authentifizierung vor dem Lesen oder Schreiben von Nachrichten erfordert. Dazu fügen wir dem Datenobjekt für Mitteilungen die folgenden Regeln hinzu. Wählen Sie im Abschnitt „Datenbank“ der Firebase Console die Option „Realtime Database“ aus und klicken Sie dann auf den Tab „Regeln“. Aktualisieren Sie die Regeln dann so:

{
  "rules": {
    "messages": {
      ".read": "auth != null",
      ".write": "auth != null"
    }
  }
}

Weitere Informationen zur Funktionsweise (einschließlich der Dokumentation zur Variablen „auth“) finden Sie in der Firebase-Sicherheitsdokumentation.

Authentifizierungs-APIs konfigurieren

Bevor Ihre Anwendung im Namen Ihrer Nutzer auf die Firebase Authentication APIs zugreifen kann, müssen Sie sie aktivieren.

  1. Rufen Sie die Firebase Console auf und wählen Sie Ihr Projekt aus.
  2. Wählen Sie Authentifizierung aus.
  3. Wählen Sie den Tab Sign-In Method (Anmeldemethode) aus.
  4. Stellen Sie den Schalter Google auf „Ein“ (blau).
  5. Klicken Sie im angezeigten Dialogfeld auf Speichern.

Wenn Sie später in diesem Codelab Fehler mit der Meldung „CONFIGURATION_NOT_FOUND“ erhalten, kehren Sie zu diesem Schritt zurück und überprüfen Sie Ihre Arbeit noch einmal.

Firebase Auth-Abhängigkeit bestätigen

Prüfen Sie, ob die Firebase Auth-Abhängigkeiten in der Datei Podfile vorhanden sind.

Podfile

pod 'Firebase/Auth'

Info.plist für Google Log-in einrichten

Sie müssen Ihrem XCode-Projekt ein benutzerdefiniertes URL-Schema hinzufügen.

  1. Öffnen Sie die Projektkonfiguration: Doppelklicken Sie in der linken Baumansicht auf den Projektnamen. Wählen Sie im Bereich „ZIELE“ Ihre App aus, dann den Tab „Info“ und maximieren Sie den Bereich „URL-Typen“.
  2. Klicken Sie auf das Pluszeichen und fügen Sie ein URL-Schema für Ihre Client-ID in umgekehrter Reihenfolge hinzu. Diesen Wert finden Sie in der Konfigurationsdatei „GoogleService-Info.plist“ unter dem Schlüssel „REVERSED_CLIENT_ID“. Kopieren Sie den Wert dieses Schlüssels und fügen Sie ihn auf der Konfigurationsseite in das Feld „URL-Schemas“ ein. Lassen Sie die anderen Felder leer.
  3. Wenn Sie fertig sind, sollte Ihre Konfiguration in etwa so aussehen (aber mit Ihren anwendungsspezifischen Werten):

1b54d5bd2f4f1448.png

clientID für Google Sign-in festlegen

Nachdem Firebase konfiguriert wurde, können wir die Client-ID verwenden, um die Google-Anmeldung in der Methode „didFinishLaunchingWithOptions:“ einzurichten.

AppDelegate.swift

  func application(_ application: UIApplication, didFinishLaunchingWithOptions
      launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  FirebaseApp.configure()
  GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
  GIDSignIn.sharedInstance().delegate = self
  return true
}

Anmelde-Handler hinzufügen

Wenn das Ergebnis des Google-Log-ins erfolgreich war, verwenden Sie das Konto zur Authentifizierung bei Firebase.

AppDelegate.swift

  func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
    if let error = error {
      print("Error \(error)")
      return
    }

    guard let authentication = user.authentication else { return }
    let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                      accessToken: authentication.accessToken)
    Auth.auth().signIn(with: credential) { (user, error) in
      if let error = error {
        print("Error \(error)")
        return
      }
    }
  }

Den Nutzer automatisch anmelden Fügen Sie dann einen Listener zu Firebase Auth hinzu, damit der Nutzer nach der erfolgreichen Anmeldung auf die App zugreifen kann. Entfernen Sie den Listener bei der Deinitialisierung.

SignInViewController.swift

  override func viewDidLoad() {
    super.viewDidLoad()
    GIDSignIn.sharedInstance().uiDelegate = self
    GIDSignIn.sharedInstance().signInSilently()
    handle = Auth.auth().addStateDidChangeListener() { (auth, user) in
      if user != nil {
        MeasurementHelper.sendLoginEvent()
        self.performSegue(withIdentifier: Constants.Segues.SignInToFp, sender: nil)
      }
    }
  }

  deinit {
    if let handle = handle {
      Auth.auth().removeStateDidChangeListener(handle)
    }
  }

Abmelden

Abmeldemethode hinzufügen

FCViewController.swift

  @IBAction func signOut(_ sender: UIButton) {
    let firebaseAuth = Auth.auth()
    do {
      try firebaseAuth.signOut()
      dismiss(animated: true, completion: nil)
    } catch let signOutError as NSError {
      print ("Error signing out: \(signOutError.localizedDescription)")
    }
  }

Nachrichten als angemeldeter Nutzer lesen

  1. Klicken Sie auf die Schaltfläche 98205811bbed9d74.pngAusführen.
  2. Sie sollten sofort zum Anmeldebildschirm weitergeleitet werden. Tippen Sie auf die Schaltfläche „Über Google anmelden“.
  3. Wenn alles funktioniert hat, sollten Sie dann zum Messaging-Bildschirm weitergeleitet werden.

6. Realtime Database aktivieren

2efe6805ef369641.png

Nachrichten importieren

Wählen Sie in Ihrem Projekt in der Firebase Console in der linken Navigationsleiste den Eintrag Datenbank aus. Wählen Sie im Dreipunkt-Menü der Datenbank die Option JSON importieren aus. Suchen Sie im Verzeichnis „friendlychat“ nach der Datei initial_messages.json, wählen Sie sie aus und klicken Sie auf die Schaltfläche Importieren. Dadurch werden alle Daten ersetzt, die sich derzeit in Ihrer Datenbank befinden. Sie können die Datenbank auch direkt bearbeiten, indem Sie Elemente mit dem grünen „+“ hinzufügen und mit dem roten „x“ entfernen.

20ccf4856b715b4c.png

Nach dem Import sollte Ihre Datenbank so aussehen:

f3e0367f1c9cd187.png

Firebase-Datenbankabhängigkeit bestätigen

Prüfen Sie im Block „dependencies“ der Datei Podfile, ob Firebase/Database enthalten ist.

Podfile

pod 'Firebase/Database'

Vorhandene Nachrichten synchronisieren

Fügen Sie Code hinzu, der neu hinzugefügte Nachrichten mit der App-Benutzeroberfläche synchronisiert.

Der Code, den Sie in diesem Abschnitt hinzufügen, hat folgende Auswirkungen:

  • Initialisieren Sie die Firebase-Datenbank und fügen Sie einen Listener hinzu, um Änderungen an der Datenbank zu verarbeiten.
  • Aktualisieren Sie DataSnapshot, damit neue Nachrichten angezeigt werden.

Ändern Sie die Methoden „deinit“, „configureDatabase“ und „tableView:cellForRow indexPath:“ von FCViewController und ersetzen Sie sie durch den unten definierten Code:

FCViewController.swift

  deinit {
    if let refHandle = _refHandle {
      self.ref.child("messages").removeObserver(withHandle: _refHandle)
    }
  }


  func configureDatabase() {
    ref = Database.database().reference()
    // Listen for new messages in the Firebase database
    _refHandle = self.ref.child("messages").observe(.childAdded, with: { [weak self] (snapshot) -> Void in
      guard let strongSelf = self else { return }
      strongSelf.messages.append(snapshot)
      strongSelf.clientTable.insertRows(at: [IndexPath(row: strongSelf.messages.count-1, section: 0)], with: .automatic)
    })
  }


  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Dequeue cell
    let cell = self.clientTable.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath)
    // Unpack message from Firebase DataSnapshot
    let messageSnapshot = self.messages[indexPath.row]
    guard let message = messageSnapshot.value as? [String: String] else { return cell }
    let name = message[Constants.MessageFields.name] ?? ""
    let text = message[Constants.MessageFields.text] ?? ""
    cell.textLabel?.text = name + ": " + text
    cell.imageView?.image = UIImage(named: "ic_account_circle")
    if let photoURL = message[Constants.MessageFields.photoURL], let URL = URL(string: photoURL),
        let data = try? Data(contentsOf: URL) {
      cell.imageView?.image = UIImage(data: data)
    }
    return cell
  }

Testnachricht synchronisieren

  1. Klicken Sie auf die Schaltfläche 98205811bbed9d74.pngAusführen.
  2. Klicken Sie auf die Schaltfläche Anmelden, um loszulegen, um das Nachrichtenfenster aufzurufen.
  3. Fügen Sie neue Nachrichten direkt in der Firebase Console hinzu. Klicken Sie dazu neben dem Eintrag „messages“ auf das grüne Pluszeichen und fügen Sie ein Objekt wie das folgende hinzu: f9876ffc8b316b14.png
  4. Prüfen Sie, ob sie in der Friendly Chat-Benutzeroberfläche angezeigt werden.

7. Nachrichten senden

„Nachricht senden“ implementieren

Werte in die Datenbank übertragen. Wenn Sie mit der Methode „push“ Daten in die Firebase Realtime Database einfügen, wird automatisch eine ID hinzugefügt. Diese automatisch generierten IDs sind fortlaufend, sodass neue Nachrichten in der richtigen Reihenfolge hinzugefügt werden.

Ändern Sie die Methode „sendMessage:“ Ihres FCViewController. Ersetzen Sie sie durch den unten definierten Code:

FCViewController.swift

  func sendMessage(withData data: [String: String]) {
    var mdata = data
    mdata[Constants.MessageFields.name] = Auth.auth().currentUser?.displayName
    if let photoURL = Auth.auth().currentUser?.photoURL {
      mdata[Constants.MessageFields.photoURL] = photoURL.absoluteString
    }

    // Push data to Firebase Database
    self.ref.child("messages").childByAutoId().setValue(mdata)
  }

Nachrichten senden

  1. Klicken Sie auf die Schaltfläche 98205811bbed9d74.pngAusführen.
  2. Klicken Sie auf Anmelden, um das Nachrichtenfenster aufzurufen.
  3. Geben Sie eine Nachricht ein und tippen Sie auf „Senden“. Die neue Nachricht sollte in der App-UI und in der Firebase Console angezeigt werden.

8. Bilder speichern und empfangen

Firebase Storage-Abhängigkeit bestätigen

Prüfen Sie im Abhängigkeitsblock der Podfile, ob Firebase/Storage enthalten ist.

Podfile

pod 'Firebase/Storage'

Cloud Storage for Firebase einrichten

So richten Sie Cloud Storage for Firebase in Ihrem Firebase-Projekt ein:

  1. Maximieren Sie im linken Bereich der Firebase Console Build und wählen Sie dann Storage aus.
  2. Klicken Sie auf Jetzt starten.
  3. Wählen Sie einen Standort für Ihren standardmäßigen Storage-Bucket aus.
    Für Buckets in US-WEST1, US-CENTRAL1 und US-EAST1 kann die kostenlose Stufe für Google Cloud Storage genutzt werden. Für Buckets an allen anderen Standorten gelten die Preise und die Nutzung von Google Cloud Storage.
  4. Klicken Sie auf Im Testmodus starten. Lesen Sie den Haftungsausschluss zu den Sicherheitsregeln.
    Später in diesem Codelab fügen Sie Sicherheitsregeln hinzu, um Ihre Daten zu schützen. Veröffentlichen Sie keine App öffentlich, ohne Sicherheitsregeln für Ihren Storage-Bucket hinzuzufügen.
  5. Klicken Sie auf Erstellen.

Firebase Storage konfigurieren

FCViewController.swift

  func configureStorage() {
    storageRef = Storage.storage().reference()
  }

Bilder in bestehenden Nachrichten empfangen

Fügen Sie Code hinzu, mit dem Bilder aus Firebase Storage heruntergeladen werden.

Ändern Sie die Methode „tableView: cellForRowAt indexPath:“ Ihres FCViewController und ersetzen Sie sie durch den unten definierten Code:

FCViewController.swift

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Dequeue cell
    let cell = self.clientTable .dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath)
    // Unpack message from Firebase DataSnapshot
    let messageSnapshot: DataSnapshot! = self.messages[indexPath.row]
    guard let message = messageSnapshot.value as? [String:String] else { return cell }
    let name = message[Constants.MessageFields.name] ?? ""
    if let imageURL = message[Constants.MessageFields.imageURL] {
      if imageURL.hasPrefix("gs://") {
        Storage.storage().reference(forURL: imageURL).getData(maxSize: INT64_MAX) {(data, error) in
          if let error = error {
            print("Error downloading: \(error)")
            return
          }
          DispatchQueue.main.async {
            cell.imageView?.image = UIImage.init(data: data!)
            cell.setNeedsLayout()
          }
        }
      } else if let URL = URL(string: imageURL), let data = try? Data(contentsOf: URL) {
        cell.imageView?.image = UIImage.init(data: data)
      }
      cell.textLabel?.text = "sent by: \(name)"
    } else {
      let text = message[Constants.MessageFields.text] ?? ""
      cell.textLabel?.text = name + ": " + text
      cell.imageView?.image = UIImage(named: "ic_account_circle")
      if let photoURL = message[Constants.MessageFields.photoURL], let URL = URL(string: photoURL),
          let data = try? Data(contentsOf: URL) {
        cell.imageView?.image = UIImage(data: data)
      }
    }
    return cell
  }

9. Bildnachrichten senden

Bilder speichern und senden

Laden Sie ein Bild vom Nutzer hoch und synchronisieren Sie dann die Speicher-URL dieses Bildes mit der Datenbank, damit das Bild in der Nachricht gesendet wird.

Ändern Sie die Methode „imagePickerController: didFinishPickingMediaWithInfo:“ von FCViewController und ersetzen Sie sie durch den unten definierten Code:

FCViewController.swift

  func imagePickerController(_ picker: UIImagePickerController,
    didFinishPickingMediaWithInfo info: [String : Any]) {
      picker.dismiss(animated: true, completion:nil)
    guard let uid = Auth.auth().currentUser?.uid else { return }

    // if it's a photo from the library, not an image from the camera
    if #available(iOS 8.0, *), let referenceURL = info[UIImagePickerControllerReferenceURL] as? URL {
      let assets = PHAsset.fetchAssets(withALAssetURLs: [referenceURL], options: nil)
      let asset = assets.firstObject
      asset?.requestContentEditingInput(with: nil, completionHandler: { [weak self] (contentEditingInput, info) in
        let imageFile = contentEditingInput?.fullSizeImageURL
        let filePath = "\(uid)/\(Int(Date.timeIntervalSinceReferenceDate * 1000))/\((referenceURL as AnyObject).lastPathComponent!)"
        guard let strongSelf = self else { return }
        strongSelf.storageRef.child(filePath)
          .putFile(from: imageFile!, metadata: nil) { (metadata, error) in
            if let error = error {
              let nsError = error as NSError
              print("Error uploading: \(nsError.localizedDescription)")
              return
            }
            strongSelf.sendMessage(withData: [Constants.MessageFields.imageURL: strongSelf.storageRef.child((metadata?.path)!).description])
          }
      })
    } else {
      guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
      let imageData = UIImageJPEGRepresentation(image, 0.8)
      let imagePath = "\(uid)/\(Int(Date.timeIntervalSinceReferenceDate * 1000)).jpg"
      let metadata = StorageMetadata()
      metadata.contentType = "image/jpeg"
      self.storageRef.child(imagePath)
        .putData(imageData!, metadata: metadata) { [weak self] (metadata, error) in
          if let error = error {
            print("Error uploading: \(error)")
            return
          }
          guard let strongSelf = self else { return }
          strongSelf.sendMessage(withData: [Constants.MessageFields.imageURL: strongSelf.storageRef.child((metadata?.path)!).description])
      }
    }
  }

Senden und Empfangen von Bildnachrichten testen

  1. Klicken Sie auf die Schaltfläche 98205811bbed9d74.pngAusführen.
  2. Klicken Sie auf Anmelden, um das Nachrichtenfenster aufzurufen.
  3. Klicken Sie auf das Symbol „Foto hinzufügen“, um ein Foto auszuwählen. Die neue Nachricht mit dem Foto sollte in der App-UI und in der Firebase Console sichtbar sein.

10. Glückwunsch!

Sie haben mithilfe von Firebase mühelos eine App für Echtzeit-Chats erstellt.

Behandelte Themen

  • Realtime Database
  • Föderierte Anmeldung
  • Speicher

Weitere Informationen