O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Firebase iOS Codelab Swift

2efe6805ef369641.png

Bem-vindo ao codelab do Chat Amigável. Neste codelab, você aprenderá como usar a plataforma Firebase para criar aplicativos iOS. Você implementará um cliente de bate-papo e monitorará seu desempenho usando o Firebase.

Este codelab também está disponível em Objective-C.

O que você aprenderá

  • Permitir que os usuários façam login.
  • Sincronize dados usando o Firebase Realtime Database.
  • Armazene arquivos binários no Firebase Storage.

O que você precisará

  • Xcode
  • CocoaPods
  • Um dispositivo de teste com iOS 8.0+ ou simulador

Como você usará este tutorial?

Leia apenas na íntegra Leia e complete os exercícios

Como classificaria sua experiência com a construção de aplicativos iOS?

Novato Intermediário Proficiente

Clone o repositório GitHub a partir da linha de comando.

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

2f4c98d858c453fe.png

Para construir o aplicativo inicial:

  1. Em uma janela de terminal, navegue até o android_studio_folder.png ios-starter/swift-starter diretório de sua amostra de download de código
  2. Run pod install --repo-update
  3. Abra o arquivo FriendlyChatSwift.xcworkspace para abrir o projeto no Xcode.
  4. Clique no 98205811bbed9d74.png Botão Executar.

Você deverá ver a tela inicial do Friendly Chat após alguns segundos. A IU deve aparecer. No entanto, neste ponto, você não pode entrar, enviar ou receber mensagens. O aplicativo será abortado com uma exceção até que você conclua a próxima etapa.

Criar projeto

De Firebase consola selecione Add Project.

Chame o projeto FriendlyChat , em seguida, clique em Criar projeto.

Captura de tela de 06-11-2015 14: 13: 39.png

Conecte seu aplicativo iOS

  1. Na tela Visão geral do projeto de seu novo projeto, clique em Adicionar Firebase ao seu aplicativo iOS.
  2. Digite o ID do pacote, como " com.google.firebase.codelab.FriendlyChatSwift ".
  3. Digite o ID App Store como " 123456 ".
  4. Clique Register App.

Adicione o arquivo GoogleService-Info.plist ao seu aplicativo

Na segunda tela clique em Download GoogleService-Info.plist baixar um arquivo de configuração que contém todos os metadados Firebase necessária para a sua aplicação. Copie o arquivo para o seu aplicativo e adicioná-lo ao alvo FriendlyChatSwift.

Agora você pode clicar no "x" no canto superior direito da janela pop-up para fechá-la - pulando as etapas 3 e 4 - pois você executará essas etapas aqui.

19d59efb213ddbdc.png

Módulo de importação do Firebase

Comece por ter certeza que a Firebase módulo é importado.

AppDelegate.swift , FCViewController.swift

import Firebase

Configure o Firebase em AppDelegate

Use o método "configure" no FirebaseApp dentro do aplicativo: função didFinishLaunchingWithOptions para configurar os serviços subjacentes do Firebase a partir do seu arquivo .plist.

AppDelegate.swift

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

Use regras para restringir a usuários autenticados

Agora adicionaremos uma regra para exigir autenticação antes de ler ou escrever qualquer mensagem. Para fazer isso, adicionamos as seguintes regras ao nosso objeto de dados de mensagens. De dentro da seção Banco de Dados de consola Firebase escolha Realtime banco de dados, em seguida, clique na guia Regras. Em seguida, atualize as regras para que tenham a seguinte aparência:

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

Para mais informações sobre como isso funciona (incluindo documentação sobre a variável "auth") ver a Firebase documentação de segurança .

Configurar APIs de autenticação

Antes que seu aplicativo possa acessar as APIs de autenticação do Firebase em nome de seus usuários, você terá que habilitá-lo

  1. Navegue para a consola Firebase e selecione seu projeto
  2. Selecione Autenticação
  3. Selecione o sinal de guia No Método
  4. Alternar a chave Google para habilitado (azul)
  5. Pressione Salvar na caixa de diálogo resultante

Se você receber erros posteriormente neste codelab com a mensagem "CONFIGURATION_NOT_FOUND", volte a esta etapa e verifique seu trabalho.

Confirme a dependência do Firebase Auth

Existem dependências Confirmar Firebase de Autenticação na Podfile arquivo.

Podfile

pod 'Firebase/Auth'

Configure seu Info.plist para o Login do Google.

Você precisará adicionar um esquema de URL personalizado ao seu projeto XCode.

  1. Abra a configuração do seu projeto: clique duas vezes no nome do projeto na visualização em árvore à esquerda. Selecione seu aplicativo na seção DESTINOS, selecione a guia Informações e expanda a seção Tipos de URL.
  2. Clique no botão + e adicione um esquema de URL para seu ID de cliente revertido. Para encontrar esse valor, abra o arquivo de configuração GoogleService-Info.plist e procure a chave REVERSED_CLIENT_ID. Copie o valor dessa chave e cole-o na caixa Esquemas de URL na página de configuração. Deixe os outros campos em branco.
  3. Quando concluído, sua configuração deve ser semelhante à seguinte (mas com os valores específicos de seu aplicativo):

1b54d5bd2f4f1448.png

Definir clientID para login do Google

Após a configuração do Firebase, podemos usar o clientID para configurar o Login do Google dentro do método "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
}

Adicione o gerenciador de login

Assim que o resultado do login do Google for bem-sucedido, use a conta para autenticar com o 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
      }
    }
  }

Faça login do usuário automaticamente. Em seguida, adicione um ouvinte ao Firebase Auth, para permitir que o usuário entre no aplicativo, após o login bem-sucedido. E remova o ouvinte no 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)
    }
  }

Sair

Adicione o método de desconexão

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

Teste de leitura de mensagens como usuário conectado

  1. Clique no 98205811bbed9d74.png Botão Executar.
  2. Você será enviado imediatamente para a tela de login. Toque no botão Login do Google.
  3. Em seguida, você deve ser enviado para a tela de mensagens se tudo funcionou bem.

2efe6805ef369641.png

Importar mensagens

Em seu projeto em Firebase consola selecionar o item de banco de dados na barra de navegação à esquerda. No menu de transbordamento do banco de dados selecione Import JSON. Procure o initial_messages.json arquivo no diretório friendlychat, selecione-o e clique no botão Import. Isso substituirá todos os dados atualmente em seu banco de dados. Você também pode editar o banco de dados diretamente, usando o + verde e o x vermelho para adicionar e remover itens.

20ccf4856b715b4c.png

Depois de importar, seu banco de dados deve ficar assim:

f3e0367f1c9cd187.png

Confirme a dependência do Firebase Database

No bloco de dependências do Podfile arquivo, confirme se Firebase/Database está incluído.

Podfile

pod 'Firebase/Database'

Sincronizar Mensagens Existentes

Adicione o código que sincroniza as mensagens recém-adicionadas à IU do aplicativo.

O código que você adicionar nesta seção irá:

  • Inicialize o banco de dados Firebase e adicione um ouvinte para lidar com as alterações feitas no banco de dados.
  • Atualizar o DataSnapshot tão novas mensagens serão mostradas.

Modifique os métodos "deinit", "configureDatabase" e "tableView: cellForRow indexPath:" do FCViewController; substitua pelo código definido abaixo:

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
  }

Teste a sincronização de mensagens

  1. Clique no 98205811bbed9d74.png Botão Executar.
  2. Clique no Entrar no botão Primeiros passos para ir para a janela de mensagens.
  3. Adicione novas mensagens diretamente no Firebase console clicando no símbolo verde + ao lado da entrada "mensagens" e adicionando um objeto como o seguinte: f9876ffc8b316b14.png
  4. Confirme se eles aparecem na IU do Friendly-Chat.

Implementar Enviar Mensagem

Envie os valores para o banco de dados. Quando você usa o método push para adicionar dados ao Firebase Realtime Database, um ID automático é adicionado. Esses IDs gerados automaticamente são sequenciais, o que garante que novas mensagens sejam adicionadas na ordem correta.

Modifique o método "sendMessage:" do seu FCViewController; substitua pelo código definido abaixo:

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

Teste de envio de mensagens

  1. Clique no 98205811bbed9d74.png Botão Executar.
  2. Clique Entrar para ir para a janela de mensagens.
  3. Digite uma mensagem e clique em enviar. A nova mensagem deve estar visível na IU do aplicativo e no console do Firebase.

Confirme a dependência de armazenamento do Firebase

No bloco de dependências do Podfile , confirmam Firebase/Storage está incluído.

Podfile

pod 'Firebase/Storage'

Ative o Firebase Storage no painel

Acesse o console do Firebase e confirme se o armazenamento está ativado com o domínio "gs: //PROJECTID.appspot.com"

b0438b37a588bcee.png

Se você estiver vendo a janela de ativação, clique em "COMEÇAR" para ativá-la com as regras padrão.

c290bbebff2cafa7.png

Configure FirebaseStorage

FCViewController.swift

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

Receber imagens em mensagens existentes

Adicione o código que faz download de imagens do Firebase Storage.

Modifique o método "tableView: cellForRowAt indexPath:" do FCViewController; substitua pelo código definido abaixo:

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
  }

Implementar, armazenar e enviar imagens

Faça upload de uma imagem do usuário e sincronize o URL de armazenamento dessa imagem com o banco de dados para que a imagem seja enviada dentro da mensagem.

Modifique o método "imagePickerController: didFinishPickingMediaWithInfo:" do seu FCViewController; substitua pelo código definido abaixo:

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

Teste de envio e recebimento de mensagens de imagem

  1. Clique no 98205811bbed9d74.png Botão Executar.
  2. Clique Entrar para ir para a janela de mensagens.
  3. Clique no ícone "adicionar uma foto" para escolher uma foto. A nova mensagem com a foto deve estar visível na IU do aplicativo e no console do Firebase.

Você usou o Firebase para criar facilmente um aplicativo de bate-papo em tempo real.

O que cobrimos

  • Realtime Database
  • Login federado
  • Armazenar

Saber mais