Firebase iOS CodeLab — szybkie ćwiczenie

1. Przegląd

2efe6805ef369641.png

Witamy w laboratorium kodowania na Przyjaznym Czacie. W tym laboratorium z programowania dowiesz się, jak korzystać z platformy Firebase do tworzenia aplikacji na iOS. Zaimplementujesz klienta czatu i będziesz monitorować jego działanie za pomocą Firebase.

To laboratorium jest również dostępne w Objective-C.

Czego się nauczysz

  • Zezwól użytkownikom na logowanie.
  • Synchronizuj dane przy użyciu bazy danych czasu rzeczywistego Firebase.
  • Przechowuj pliki binarne w Firebase Storage.

Co będziesz potrzebował

  • Xkod
  • CocoaPods
  • Urządzenie testowe z systemem iOS 8.0+ lub symulatorem

Jak będziesz korzystać z tego samouczka?

Przeczytaj to tylko Przeczytaj i wykonaj ćwiczenia

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

Nowicjusz Mediator Biegły

2. Pobierz przykładowy kod

Sklonuj repozytorium GitHub z wiersza polecenia.

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

3. Zbuduj aplikację startową

2f4c98d858c453fe.png

Aby zbudować aplikację startową:

  1. W oknie terminala przejdź do android_studio_folder.png ios-starter/swift-starter katalog z przykładowy kod do pobrania
  2. Run pod install --repo-update
  3. Otwórz plik FriendlyChatSwift.xcworkspace, aby otworzyć projekt w Xcode.
  4. Kliknij 98205811bbed9d74.png Uruchom przycisk.

Po kilku sekundach powinien pojawić się ekran główny Czatu Przyjaznego. Powinien pojawić się interfejs użytkownika. Jednak w tym momencie nie możesz się zalogować, wysyłać ani odbierać wiadomości. Aplikacja zostanie przerwana z wyjątkiem, dopóki nie wykonasz następnego kroku.

4. Utwórz projekt konsoli Firebase

Utwórz projekt

Od Firebase konsoli wybierz Dodaj Project.

Zadzwoń do projektu FriendlyChat , a następnie kliknij przycisk Utwórz projekt.

Zrzut ekranu z 06.11.2015 14:13:39.png

Podłącz swoją aplikację na iOS

  1. Na ekranie Przegląd projektu swojego nowego projektu, kliknij przycisk Dodaj Firebase do swojej aplikacji na iOS.
  2. Wprowadź identyfikator pakietu, jako „ com.google.firebase.codelab.FriendlyChatSwift ”.
  3. Wprowadź identyfikator App Store jako „ 123456 ”.
  4. Kliknij Register App.

Dodaj plik GoogleService-Info.plist do swojej aplikacji

Na drugim ekranie kliknij Pobierz GoogleService-Info.plist do pobrania pliku konfiguracyjnego, który zawiera wszystkie niezbędne metadane Firebase dla swojej aplikacji. Skopiuj ten plik do aplikacji i dodać go do celu 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 kroki tutaj.

19d59efb213ddbdc.png

Importuj moduł Firebase

Zacznij od upewniając się Firebase moduł jest importowany.

AppDelegate.swift , FCViewController.swift

import Firebase

Skonfiguruj Firebase w 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. Zidentyfikuj użytkowników

Użyj reguł, aby ograniczyć się do uwierzytelnionych użytkowników

Dodamy teraz regułę wymagającą uwierzytelnienia przed odczytaniem lub napisaniem jakichkolwiek wiadomości. W tym celu do naszego obiektu danych komunikatów dodajemy następujące reguły. Od wewnątrz sekcji danych z konsoli Firebase wybrać bazy danych w czasie rzeczywistym, a następnie kliknąć na zakładce Reguły. Następnie zaktualizuj reguły, aby wyglądały tak:

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

Aby uzyskać więcej informacji na temat, jak to działa (łącznie z dokumentacją dotyczącą zmiennej „auth”) zobaczyć Firebase dokumentacji zabezpieczeń .

Skonfiguruj interfejsy API uwierzytelniania

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

  1. Przejdź do konsoli Firebase i wybrać projekt
  2. Wybierz Authentication
  3. Wybierz znakiem kartę w metodzie
  4. Włącz przełącznik Google na Enabled (niebieski)
  5. Naciśnij przycisk Zapisz w oknie dialogowym

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

Potwierdź zależność uwierzytelniania Firebase

Zależności Potwierdź Firebase uwierzytelniania istnieje w Podfile pliku.

Podfile

pod 'Firebase/Auth'

Skonfiguruj plik Info.plist do logowania przez Google.

Musisz dodać niestandardowy schemat adresu URL do projektu XCode.

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

1b54d5bd2f4f1448.png

Ustaw identyfikator klienta dla logowania Google

Po skonfigurowaniu Firebase możemy użyć identyfikatora klienta do skonfigurowania logowania 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
}

Dodaj obsługę logowania

Gdy logowanie przez Google się powiedzie, 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 zaloguj użytkownika. Następnie dodaj detektor do Firebase Auth, aby umożliwić użytkownikowi dostęp do aplikacji po pomyślnym zalogowaniu. I usuń detektor po 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ę

Dodaj metodę wylogowania

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

Przetestuj odczytywanie wiadomości jako zalogowanego użytkownika

  1. Kliknij 98205811bbed9d74.png Uruchom przycisk.
  2. Powinieneś natychmiast przejść do ekranu logowania. Stuknij przycisk Zaloguj się przez Google.
  3. Powinieneś zostać wysłany do ekranu wiadomości, jeśli wszystko działa dobrze.

6. Aktywuj bazę danych czasu rzeczywistego

2efe6805ef369641.png

Importuj wiadomości

W swoim projekcie w Firebase konsoli wybierz pozycję bazy danych na lewym pasku nawigacyjnym. W menu przelewowym Bazie wybierz Importuj JSON. Przejdź do initial_messages.json pliku w katalogu friendlychat, wybierz go, a następnie kliknij przycisk Importuj. Spowoduje to zastąpienie wszelkich danych znajdujących się obecnie w Twojej bazie danych. Możesz także edytować bazę danych bezpośrednio, używając zielonego + i czerwonego x, aby dodawać i usuwać elementy.

20ccf4856b715b4c.png

Po zaimportowaniu Twoja baza danych powinna wyglądać tak:

f3e0367f1c9cd187.png

Potwierdź zależność bazy danych Firebase

W bloku Zależności w Podfile pliku upewnij się, że Firebase/Database jest włączone.

Podfile

pod 'Firebase/Database'

Synchronizuj istniejące 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 do obsługi zmian wprowadzonych w bazie danych.
  • Zaktualizuj DataSnapshot więc nowe wiadomości będą wyświetlane.

Zmodyfikuj metody „deinit”, „configureDatabase” i „tableView:cellForRow indexPath:” w FCViewController; zastąp 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
  }

Przetestuj synchronizację wiadomości

  1. Kliknij 98205811bbed9d74.png Uruchom przycisk.
  2. Kliknij Zaloguj się, by przycisk zaczęło iść do okna wiadomości.
  3. Dodaj nowe wiadomości bezpośrednio w konsoli Firebase, klikając zielony symbol + obok pozycji „wiadomości” i dodając obiekt podobny do następującego: f9876ffc8b316b14.png
  4. Potwierdź, że pojawiają się w interfejsie Friendly-Chat.

7. Wyślij wiadomości

Zaimplementuj Wyślij wiadomość

Prześlij wartości do bazy danych. Gdy używasz metody push do dodawania danych do Bazy danych czasu rzeczywistego Firebase, zostanie dodany automatyczny identyfikator. Te automatycznie generowane identyfikatory są sekwencyjne, co zapewnia, że ​​nowe wiadomości będą dodawane we właściwej kolejności.

Zmodyfikuj metodę "sendMessage:" swojego FCViewController; zastąp 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)
  }

Przetestuj wysyłanie wiadomości

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

8. Przechowuj i odbieraj obrazy

Potwierdź zależność pamięci Firebase

W bloku Zależności w Podfile potwierdź Firebase/Storage jest włączone.

Podfile

pod 'Firebase/Storage'

Aktywuj pamięć Firebase w panelu

Przejdź do konsoli Firebase i upewnij się, że pamięć masowa została aktywowana w domenie „gs://PROJECTID.appspot.com”

b0438b37a588bcee.png

Jeśli zamiast tego zobaczysz okno aktywacji, kliknij „ROZPOCZNIJ”, aby aktywować je z domyślnymi regułami.

c290bbebff2cafa7.png

Skonfiguruj FirebaseStorage

FCViewController.swift

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

Odbieraj obrazy w istniejących wiadomościach

Dodaj kod, który pobiera obrazy z Firebase Storage.

Zmodyfikuj metodę „tableView: cellForRowAt indexPath:” kontrolera FCViewController; zastąp 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. Wyślij wiadomości graficzne

Zaimplementuj Przechowuj i wysyłaj obrazy

Prześlij obraz od użytkownika, a następnie zsynchronizuj adres URL przechowywania tego obrazu z bazą danych, aby ten obraz został wysłany wewnątrz wiadomości.

Zmodyfikuj metodę „imagePickerController: didFinishPickingMediaWithInfo:” swojego kontrolera FCViewController; zastąp 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])
      }
    }
  }

Przetestuj wysyłanie i odbieranie wiadomości obrazkowych

  1. Kliknij 98205811bbed9d74.png Uruchom przycisk.
  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 oraz w konsoli Firebase.

10. Gratulacje!

Używasz Firebase do łatwego tworzenia aplikacji do czatu w czasie rzeczywistym.

Co omówiliśmy

  • Baza danych czasu rzeczywistego
  • Logowanie federacyjne
  • Składowanie

Ucz się więcej