Firebase iOS Codelab Swift

1. Übersicht

2efe6805ef369641.png

Willkommen beim Codelab für 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.

Aufgaben in diesem Lab

  • Erlauben Sie Nutzern, sich anzumelden.
  • Synchronisieren Sie Daten mithilfe der Firebase Realtime Database.
  • Binärdateien in Firebase Storage speichern

Voraussetzungen

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

Wie möchten Sie diese Anleitung verwenden?

Nur durchlesen Durchlesen und die Übungen absolvieren

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. Rufen Sie in einem Terminalfenster das Verzeichnis android_studio_folder.pngios-starter/swift-starter aus dem heruntergeladenen Beispielcode auf.
  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 wenigen Sekunden sollte der Startbildschirm von Friendly Chat angezeigt werden. Die Benutzeroberfläche sollte angezeigt werden. Sie können sich jedoch noch 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 Console-Projekt erstellen

Projekt erstellen

Wählen Sie in der Firebase Console die Option Projekt hinzufügen aus.

Benennen Sie das Projekt in FriendlyChat um und klicken Sie dann auf Create Project (Projekt erstellen).

Screenshot from 2015-11-06 14:13:39.png

Firebase-Preismodell upgraden

Damit Sie Cloud Storage for Firebase verwenden können, muss Ihr Firebase-Projekt den Blaze-Tarif (Pay as you go) haben. Das bedeutet, dass es mit einem Cloud-Rechnungskonto verknüpft sein muss.

So führen Sie ein Upgrade auf den Blaze-Tarif durch:

  1. Wählen Sie in der Firebase Console Tarif upgraden 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 Console zurückkehren, um das Upgrade abzuschließen.

iOS-App verknüpfen

  1. Klicken Sie auf dem Bildschirm „Projektübersicht“ 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.

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

Klicken Sie auf dem zweiten Bildschirm auf GoogleService-Info.plist herunterladen, um eine Konfigurationsdatei mit allen erforderlichen Firebase-Metadaten für Ihre App herunterzuladen. 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 auf das „x“ klicken, um es zu schließen. Überspringen Sie die Schritte 3 und 4, da Sie diese hier ausführen.

19d59efb213ddbdc.png

Firebase-Modul importieren

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

AppDelegate.swift, FCViewController.swift

import Firebase

Firebase in AppDelegate konfigurieren

Verwenden Sie die Methode „configure“ in FirebaseApp in der Funktion „application:didFinishLaunchingWithOptions“, um die zugrunde liegenden 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 unserem Nachrichtendatenobjekt die folgenden Regeln hinzu. Wählen Sie in der Firebase Console im Bereich „Datenbank“ die Option „Realtime Database“ aus und klicken Sie dann auf den Tab „Regeln“. Aktualisieren Sie dann die Regeln so:

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

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

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 „Aktiviert“ (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.

Abhängigkeit von Firebase Auth prüfen

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

Podfile

pod 'Firebase/Auth'

Richten Sie Ihre Info.plist-Datei für Google Sign-in ein.

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 „ZIELGRUPPE“ Ihre App aus, klicken Sie auf den Tab „Info“ und maximieren Sie den Bereich „URL-Typen“.
  2. Klicken Sie auf die Schaltfläche „+“ und fügen Sie ein URL-Schema für Ihre Client-ID in umgekehrter Reihenfolge hinzu. Öffnen Sie dazu die Konfigurationsdatei „GoogleService-Info.plist“ und suchen Sie nach 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. Die Konfiguration sollte dann in etwa so aussehen (aber mit Ihren anwendungsspezifischen Werten):

1b54d5bd2f4f1448.png

Client-ID für Google Sign-In festlegen

Nachdem Firebase konfiguriert ist, können wir die clientID 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 die Google-Anmeldung erfolgreich war, authentifizieren Sie sich mit dem Konto 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
      }
    }
  }

Nutzer automatisch anmelden Fügen Sie dann Firebase Auth einen Listener hinzu, damit der Nutzer nach der erfolgreichen Anmeldung in die App gelangt. Und entfernen Sie den Listener bei der Deaktivierung.

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

Methode zum Abmelden 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)")
    }
  }

Lesen von Nachrichten als angemeldeter Nutzer testen

  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 richtig funktioniert hat, sollten Sie zum Bildschirm für Nachrichten 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. Rufen Sie die Datei initial_messages.json im Verzeichnis „friendlychat“ auf, 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. Verwenden Sie dazu das grüne Pluszeichen + und das rote Kreuz ×, um Elemente hinzuzufügen oder zu 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.

Mit dem Code, den Sie in diesem Abschnitt hinzufügen, wird Folgendes ausgeführt:

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

Ändern Sie die Methoden „deinit“, „configureDatabase“ und „tableView:cellForRow indexPath:“ Ihres FCViewControllers 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
  }

Synchronisierung von Nachrichten testen

  1. Klicken Sie auf die Schaltfläche 98205811bbed9d74.pngAusführen.
  2. Klicken Sie auf die Schaltfläche Jetzt anmelden, um das Nachrichtenfenster aufzurufen.
  3. Sie können neue Nachrichten direkt in der Firebase Console hinzufügen. Klicken Sie dazu auf das grüne Pluszeichen neben dem Eintrag „messages“ 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 an die Datenbank übergeben Wenn Sie der Firebase Realtime Database mit der Push-Methode Daten hinzufügen, wird eine automatische ID hinzugefügt. Diese automatisch generierten IDs sind sequenziell, sodass neue Nachrichten in der richtigen Reihenfolge hinzugefügt werden.

Ändern Sie die Methode „sendMessage:“ Ihres FCViewControllers und 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)
  }

Senden von Nachrichten testen

  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 klicken Sie auf „Senden“. Die neue Nachricht sollte in der App-UI und in der Firebase Console angezeigt werden.

8. Bilder speichern und empfangen

Abhängigkeit von Firebase Storage 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 die Option Build und wählen Sie dann Storage aus.
  2. Klicken Sie auf Jetzt starten.
  3. Wählen Sie einen Speicherort für Ihren Standard-Storage-Bucket aus.
    Für Buckets in US-WEST1, US-CENTRAL1 und US-EAST1 kann die Stufe „Immer kostenlos“ für Google Cloud Storage genutzt werden. Für Buckets an allen anderen Speicherorten gelten die Preise und Nutzungsbedingungen für 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 oder verteilen Sie keine App, ohne Sicherheitsregeln für Ihren Speicher-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, der Bilder aus Firebase Storage herunterlädt.

Ändern Sie die Methode „tableView: cellForRowAt indexPath:“ Ihres FCViewControllers 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 die Speicher-URL dieses Bildes mit der Datenbank, damit das Bild in der Nachricht gesendet wird.

Ändern Sie die Methode „imagePickerController: didFinishPickingMediaWithInfo:“ Ihres FCViewControllers 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 angezeigt werden.

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