1. Übersicht
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?
Wie würden Sie Ihre Erfahrung mit der Entwicklung von iOS-Apps bewerten?
2. Beispielcode abrufen
Klonen Sie das GitHub-Repository über die Befehlszeile.
$ git clone https://github.com/firebase/codelab-friendlychat-ios
3. Start-App erstellen
So erstellen Sie die Start-App:
- Wechseln Sie in einem Terminalfenster zum Verzeichnis
ios-starter/swift-starter
aus dem heruntergeladenen Beispielcode. - Führen Sie
pod install --repo-update
aus - Öffnen Sie die Datei „FriendlyChatSwift.xcworkspace“, um das Projekt in Xcode zu öffnen.
- Klicken Sie auf die Schaltfläche
Ausfü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
- Melden Sie sich mit Ihrem Google-Konto in der Firebase Console an.
- Klicken Sie auf die Schaltfläche, um ein neues Projekt zu erstellen, und geben Sie dann einen Projektnamen ein (z. B.
FriendlyChat
).
- Klicken Sie auf Weiter.
- Lesen und akzeptieren Sie bei Aufforderung die Firebase-Nutzungsbedingungen und klicken Sie dann auf Weiter.
- (Optional) Aktivieren Sie die KI-Unterstützung in der Firebase Console (als „Gemini in Firebase“ bezeichnet).
- Für dieses Codelab benötigen Sie kein Google Analytics. Deaktivieren Sie daher die Google Analytics-Option.
- 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:
- Wählen Sie in der Firebase Console die Option zum Upgraden Ihres Abos aus.
- 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
- Klicken Sie auf der Übersichtsseite Ihres neuen Projekts auf Firebase zu meiner iOS-App hinzufügen.
- Geben Sie die Bundle-ID als „
com.google.firebase.codelab.FriendlyChatSwift
“ ein. - Geben Sie die App Store-ID als „
123456
“ ein. - 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.
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.
- Rufen Sie die Firebase Console auf und wählen Sie Ihr Projekt aus.
- Wählen Sie Authentifizierung aus.
- Wählen Sie den Tab Sign-In Method (Anmeldemethode) aus.
- Stellen Sie den Schalter Google auf „Ein“ (blau).
- 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.
- Ö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“.
- 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.
- Wenn Sie fertig sind, sollte Ihre Konfiguration in etwa so aussehen (aber mit Ihren anwendungsspezifischen Werten):
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
- Klicken Sie auf die Schaltfläche
Ausführen.
- Sie sollten sofort zum Anmeldebildschirm weitergeleitet werden. Tippen Sie auf die Schaltfläche „Über Google anmelden“.
- Wenn alles funktioniert hat, sollten Sie dann zum Messaging-Bildschirm weitergeleitet werden.
6. Realtime Database aktivieren
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.
Nach dem Import sollte Ihre Datenbank so aussehen:
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
- Klicken Sie auf die Schaltfläche
Ausführen.
- Klicken Sie auf die Schaltfläche Anmelden, um loszulegen, um das Nachrichtenfenster aufzurufen.
- 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:
- 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
- Klicken Sie auf die Schaltfläche
Ausführen.
- Klicken Sie auf Anmelden, um das Nachrichtenfenster aufzurufen.
- 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:
- Maximieren Sie im linken Bereich der Firebase Console Build und wählen Sie dann Storage aus.
- Klicken Sie auf Jetzt starten.
- Wählen Sie einen Standort für Ihren standardmäßigen Storage-Bucket aus.
Für Buckets inUS-WEST1
,US-CENTRAL1
undUS-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. - 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. - 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
- Klicken Sie auf die Schaltfläche
Ausführen.
- Klicken Sie auf Anmelden, um das Nachrichtenfenster aufzurufen.
- 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