Firebase iOS Codelab Swift

1. Przegląd

2efe6805ef369641.png

Witamy w samouczku Friendly Chat. Z tego ćwiczenia w Codelabs dowiesz się, jak tworzyć aplikacje na iOS przy użyciu platformy Firebase. Wdrożysz klienta czatu i będziesz monitorować jego wydajność za pomocą Firebase.

Czego się nauczysz

  • Zezwalaj użytkownikom na logowanie się.
  • Synchronizuj dane za pomocą Bazy danych czasu rzeczywistego Firebase.
  • przechowywanie plików binarnych w Pamięci Firebase,

Czego potrzebujesz

  • Xcode
  • CocoaPods
  • urządzenie testowe z systemem iOS 8.0 lub nowszym albo symulator;

Jak zamierzasz wykorzystać ten samouczek?

Tylko przeczytaj Przeczytaj i wykonaj ćwiczenia

Jak oceniasz swoje doświadczenie w tworzeniu aplikacji na iOS?

Początkujący Średnio zaawansowany Zaawansowany

2. Pobieranie przykładowego kodu

Sklonuj repozytorium GitHub z wiersza poleceń.

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

3. Tworzenie aplikacji startowej

2f4c98d858c453fe.png

Aby skompilować aplikację startową:

  1. W oknie terminala przejdź do katalogu android_studio_folder.pngios-starter/swift-starter pobranego przykładowego kodu.
  2. Uruchom pod install --repo-update
  3. Otwórz plik FriendlyChatSwift.xcworkspace, aby otworzyć projekt w Xcode.
  4. Kliknij przycisk 98205811bbed9d74.pngUruchom.

Po kilku sekundach powinien pojawić się ekran główny aplikacji Friendly Chat. Powinien pojawić się interfejs. Nie możesz się jednak zalogować ani wysyłać i odbierać wiadomości. Aplikacja zostanie przerwana z wyjątkiem, dopóki nie wykonasz następnego kroku.

4. Konfigurowanie projektu Firebase

Tworzenie nowego projektu Firebase

  1. Zaloguj się w konsoli Firebase, korzystając ze swojego konta Google.
  2. Kliknij przycisk, aby utworzyć nowy projekt, a potem wpisz jego nazwę (np. FriendlyChat).
  3. Kliknij Dalej.
  4. Po wyświetleniu monitu przeczytaj i zaakceptuj warunki usługi Firebase, a potem kliknij Dalej.
  5. (Opcjonalnie) Włącz w konsoli Firebase pomoc AI (nazywaną „Gemini w Firebase”).
  6. W tym samouczku nie potrzebujesz Google Analytics, więc wyłącz opcję Google Analytics.
  7. Kliknij Utwórz projekt, poczekaj, aż projekt zostanie udostępniony, a następnie kliknij Dalej.

Uaktualnianie abonamentu Firebase

Aby korzystać z Cloud Storage dla Firebase, Twój projekt Firebase musi być objęty abonamentem z płatnością według wykorzystania (Blaze), co oznacza, że jest połączony z kontem rozliczeniowym Cloud.

  • Konto rozliczeniowe Cloud wymaga formy płatności, np. karty kredytowej.
  • Jeśli dopiero zaczynasz korzystać z Firebase i Google Cloud, sprawdź, czy możesz otrzymać środki w wysokości 300 USD i bezpłatne konto rozliczeniowe Cloud.
  • Jeśli wykonujesz te ćwiczenia w ramach wydarzenia, zapytaj organizatora, czy są dostępne środki w Google Cloud.

Aby przenieść projekt na abonament Blaze:

  1. W konsoli Firebase wybierz przejście na wyższy abonament.
  2. Wybierz pakiet Blaze. Postępuj zgodnie z instrukcjami wyświetlanymi na ekranie, aby połączyć konto rozliczeniowe Cloud z projektem.
    Jeśli w ramach tego przejścia na wyższy abonament konieczne było utworzenie konta rozliczeniowego Cloud, może być konieczne powrócenie do procesu przejścia na wyższy abonament w konsoli Firebase, aby go dokończyć.

Łączenie aplikacji na iOS

  1. Na ekranie Przegląd projektu nowego projektu kliknij Dodaj Firebase do aplikacji na iOS.
  2. Wpisz identyfikator pakietu w formacie „com.google.firebase.codelab.FriendlyChatSwift”.
  3. Wpisz identyfikator App Store w formacie „123456”.
  4. Kliknij Zarejestruj aplikację.

Dodawanie pliku GoogleService-Info.plist do aplikacji

Na drugim ekranie kliknij Download GoogleService-Info.plist (Pobierz GoogleService-Info.plist), aby pobrać plik konfiguracyjny zawierający wszystkie niezbędne metadane Firebase dla Twojej aplikacji. Skopiuj ten plik do aplikacji i dodaj go do elementu docelowego FriendlyChatSwift.

Możesz teraz kliknąć „x” w prawym górnym rogu wyskakującego okienka, aby je zamknąć (pomijając kroki 3 i 4), ponieważ wykonasz te czynności tutaj.

19d59efb213ddbdc.png

Importowanie modułu Firebase

Zacznij od sprawdzenia, czy moduł Firebase jest zaimportowany.

AppDelegate.swift, FCViewController.swift

import Firebase

Konfigurowanie Firebase w pliku AppDelegate

Użyj metody „configure” w FirebaseApp w funkcji application:didFinishLaunchingWithOptions, aby skonfigurować podstawowe usługi Firebase z pliku .plist.

AppDelegate.swift

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

5. Identyfikowanie użytkowników

Używanie reguł do ograniczania dostępu do uwierzytelnionych użytkowników

Teraz dodamy regułę, która będzie wymagać uwierzytelniania przed odczytaniem lub zapisaniem jakichkolwiek wiadomości. W tym celu dodajemy do obiektu danych wiadomości te reguły: W sekcji Baza danych w konsoli Firebase wybierz Realtime Database, a następnie kliknij kartę Reguły. Następnie zaktualizuj reguły, aby wyglądały tak:

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

Więcej informacji o tym, jak to działa (w tym dokumentację zmiennej „auth”), znajdziesz w dokumentacji zabezpieczeń Firebase.

Konfigurowanie interfejsów API uwierzytelniania

Zanim aplikacja będzie mogła uzyskiwać dostęp do interfejsów API uwierzytelniania Firebase w imieniu użytkowników, musisz ją włączyć.

  1. Otwórz konsolę Firebase i wybierz projekt.
  2. Wybierz Uwierzytelnianie.
  3. Wybierz kartę Metoda logowania.
  4. Ustaw przełącznik Google w pozycji włączonej (niebieskiej).
  5. W wyświetlonym oknie kliknij Zapisz.

Jeśli w dalszej części tego samouczka pojawią się błędy z komunikatem „CONFIGURATION_NOT_FOUND”, wróć do tego kroku i dokładnie sprawdź swoją pracę.

Potwierdź zależność od Uwierzytelniania Firebase

Sprawdź, czy w pliku Podfile znajdują się zależności uwierzytelniania Firebase.

Podfile

pod 'Firebase/Auth'

Skonfiguruj plik Info.plist na potrzeby logowania przez Google.

Musisz dodać do projektu XCode niestandardowy schemat adresu URL.

  1. Otwórz konfigurację projektu: w widoku drzewa po lewej stronie kliknij dwukrotnie nazwę projektu. W sekcji CELE wybierz aplikację, a potem kliknij kartę Informacje i rozwiń sekcję Typy adresów URL.
  2. Kliknij przycisk +, a następnie dodaj schemat adresu URL dla odwróconego identyfikatora klienta. Aby znaleźć tę wartość, otwórz plik konfiguracyjny GoogleService-Info.plist i wyszukaj klucz REVERSED_CLIENT_ID. Skopiuj wartość tego klucza i wklej ją w polu Schematy URL na stronie konfiguracji. Pozostałe pola pozostaw puste.
  3. Po zakończeniu konfiguracja powinna wyglądać podobnie do tej poniżej (ale z wartościami specyficznymi dla Twojej aplikacji):

1b54d5bd2f4f1448.png

Ustawianie identyfikatora klienta na potrzeby logowania przez Google

Po skonfigurowaniu Firebase możemy użyć identyfikatora klienta do skonfigurowania logowania przez Google w metodzie „didFinishLaunchingWithOptions:”.

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
}

Dodawanie funkcji obsługi logowania

Gdy logowanie przez Google zakończy się powodzeniem, użyj konta do uwierzytelnienia w 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
      }
    }
  }

automatycznie zalogować użytkownika; Następnie dodaj do Firebase Auth odbiornik, który po zalogowaniu się użytkownika umożliwi mu dostęp do aplikacji. Usuń detektor podczas wywoływania funkcji deinit.

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

Wyloguj się

Dodawanie metody wylogowywania

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

Testowanie odczytywania wiadomości jako zalogowany użytkownik

  1. Kliknij przycisk 98205811bbed9d74.pngUruchom.
  2. Powinno nastąpić natychmiastowe przekierowanie na ekran logowania. Kliknij przycisk logowania przez Google.
  3. Jeśli wszystko przebiegło prawidłowo, powinna się otworzyć ekran wiadomości.

6. Aktywowanie Bazy danych czasu rzeczywistego

2efe6805ef369641.png

Importowanie wiadomości

W projekcie w konsoli Firebase wybierz element Baza danych na pasku nawigacyjnym po lewej stronie. W menu dodatkowym bazy danych wybierz Importuj JSON. Przejdź do pliku initial_messages.json w katalogu friendlychat, wybierz go i kliknij przycisk Importuj. Spowoduje to zastąpienie wszystkich danych znajdujących się obecnie w Twojej bazie danych. Możesz też edytować bazę danych bezpośrednio, używając zielonego znaku + i czerwonego znaku x do dodawania i usuwania elementów.

20ccf4856b715b4c.png

Po zaimportowaniu baza danych powinna wyglądać tak:

f3e0367f1c9cd187.png

Potwierdź zależność od bazy danych Firebase

W bloku zależności pliku Podfile sprawdź, czy znajduje się w nim Firebase/Database.

Podfile

pod 'Firebase/Database'

Synchronizowanie istniejących wiadomości

Dodaj kod, który synchronizuje nowo dodane wiadomości z interfejsem aplikacji.

Kod dodany w tej sekcji:

  • Zainicjuj bazę danych Firebase i dodaj odbiornik, który będzie obsługiwać zmiany wprowadzane w bazie danych.
  • Zaktualizuj aplikację DataSnapshot, aby wyświetlać nowe wiadomości.

Zmodyfikuj metody „deinit”, „configureDatabase” i „tableView:cellForRow indexPath:” w klasie FCViewController, zastępując je kodem zdefiniowanym poniżej:

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
  }

Testowanie synchronizacji wiadomości

  1. Kliknij przycisk 98205811bbed9d74.pngUruchom.
  2. Kliknij przycisk Zaloguj się, aby rozpocząć, aby przejść do okna wiadomości.
  3. Dodaj nowe wiadomości bezpośrednio w konsoli Firebase. Aby to zrobić, kliknij zielony symbol + obok pozycji „messages” i dodaj obiekt podobny do tego: f9876ffc8b316b14.png
  4. Sprawdź, czy są widoczne w interfejsie Friendly-Chat.

7. Wysyłanie wiadomości

Wdrażanie funkcji wysyłania wiadomości

Przekazywanie wartości do bazy danych. Gdy używasz metody push do dodawania danych do Bazy danych czasu rzeczywistego Firebase, automatycznie dodawany jest identyfikator. Te wygenerowane automatycznie identyfikatory są sekwencyjne, co zapewnia dodawanie nowych wiadomości we właściwej kolejności.

Zmodyfikuj metodę „sendMessage:” w pliku FCViewController, zastępując ją kodem zdefiniowanym poniżej:

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

Testowanie wysyłania wiadomości

  1. Kliknij przycisk 98205811bbed9d74.pngUruchom.
  2. Kliknij Zaloguj się, aby przejść do okna wiadomości.
  3. Wpisz wiadomość i kliknij Wyślij. Nowa wiadomość powinna być widoczna w interfejsie aplikacji i w konsoli Firebase.

8. Przechowywanie i odbieranie obrazów

Potwierdź zależność od Pamięci Firebase

W bloku zależności w pliku Podfile sprawdź, czy jest uwzględniona zależność Firebase/Storage.

Podfile

pod 'Firebase/Storage'

Konfigurowanie Cloud Storage dla Firebase

Aby skonfigurować Cloud Storage dla Firebase w projekcie Firebase:

  1. W panelu po lewej stronie konsoli Firebase rozwiń Kompilacja, a następnie wybierz Storage.
  2. Kliknij Rozpocznij.
  3. Wybierz lokalizację domyślnego zasobnika Storage.
    Zasobniki w regionach US-WEST1, US-CENTRAL1 i US-EAST1 mogą korzystać z poziomu „Zawsze bezpłatny” w Google Cloud Storage. W przypadku zasobników w innych lokalizacjach obowiązuje cennik i wykorzystanie Google Cloud Storage.
  4. Kliknij Uruchom w trybie testowym. Przeczytaj wyłączenie odpowiedzialności dotyczące reguł bezpieczeństwa.
    W dalszej części tego laboratorium dodasz reguły bezpieczeństwa, aby zabezpieczyć swoje dane. Nieudostępniaj aplikacji publicznie bez dodania reguł bezpieczeństwa do zasobnika Storage.
  5. Kliknij Utwórz.

Konfigurowanie Firebase Storage

FCViewController.swift

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

Otrzymywanie obrazów w istniejących wiadomościach

Dodaj kod, który pobiera obrazy z Pamięci Firebase.

Zmodyfikuj metodę „tableView: cellForRowAt indexPath:” w pliku FCViewController, zastępując ją kodem zdefiniowanym poniżej:

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. Wysyłanie wiadomości z obrazami

Wdrażanie funkcji przechowywania i wysyłania obrazów

Prześlij obraz od użytkownika, a następnie zsynchronizuj adres URL przechowywania tego obrazu z bazą danych, aby obraz był wysyłany w wiadomości.

Zmodyfikuj metodę „imagePickerController: didFinishPickingMediaWithInfo:” w pliku FCViewController, zastępując ją kodem zdefiniowanym poniżej:

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

Testowanie wysyłania i odbierania wiadomości z obrazami

  1. Kliknij przycisk 98205811bbed9d74.pngUruchom.
  2. Kliknij Zaloguj się, aby przejść do okna wiadomości.
  3. Kliknij ikonę „Dodaj zdjęcie”, aby wybrać zdjęcie. Nowa wiadomość ze zdjęciem powinna być widoczna w interfejsie aplikacji i w konsoli Firebase.

10. Gratulacje!

Za pomocą Firebase możesz łatwo utworzyć aplikację do czatu w czasie rzeczywistym.

Omówione zagadnienia

  • Baza danych czasu rzeczywistego
  • Logowanie sfederowane
  • Miejsce na dane

Więcej informacji