Neste tutorial, mostramos como desenvolver um app para iOS com armazenamento de dados de back-end, sincronização em tempo real e geração de logs de eventos do usuário usando o Firebase. Os servlets Java em execução no ambiente flexível do App Engine detectam e processam novos registros de usuário armazenados no Firebase.
Nas instruções, veja como fazer isso usando o Firebase e o ambiente flexível do App Engine.
Use seu aplicativo para processar dados do usuário ou orquestrar eventos. Para isso, estenda o Firebase com o ambiente flexível do App Engine e faça a sincronização automática de dados em tempo real.
Com o app de amostra Playchat, as mensagens de bate-papo são armazenadas no Firebase Realtime Database, onde esses dados são sincronizados automaticamente com os dispositivos. Nesse aplicativo, os logs de eventos do usuário também são gravados no Firebase. Para saber mais sobre como o banco de dados sincroniza dados, consulte Como funciona? na documentação do Firebase.
Veja no diagrama abaixo a arquitetura do cliente do Playchat.
Um conjunto de servlets Java em execução no ambiente flexível do App Engine é registrado como listener no Firebase. Eles respondem aos logs de evento do novo usuário e processam os dados desses logs. As transações são usadas para garantir que o processamento de cada log de evento do usuário seja feito apenas por um servlet.
Veja no diagrama abaixo a arquitetura do servidor do Playchat.
A comunicação entre o app e o servlet acontece em três partes:
Quando um novo usuário faz login no Playchat, o app solicita um servlet de registro para esse usuário adicionando uma entrada em
/inbox/
no Firebase Realtime Database.Um dos servlets aceita a atribuição por meio da atualização do valor da entrada para seu identificador de servlet. Uma transação do Firebase é usada para garantir que ele seja o único a atualizar o valor. Depois disso, a solicitação é ignorada por todos os outros servlets.
Quando o usuário faz login/logout ou muda para um novo canal, o Playchat registra a ação em
/inbox/[SERVLET_ID]/[USER_ID]/
, em que[SERVLET_ID]
é o identificador da instância do servlet e[USER_ID]
é um valor de hash que representa o usuário.O servlet monitora a inclusão de novas entradas na caixa de entrada e coleta os dados de registro.
Neste aplicativo de amostra, os dados do registro são copiados localmente e exibidos em uma página da Web pelos servlets. Em uma versão de produção deste app, os servlets processam os dados de registro ou copiam esses dados para o Cloud Storage, o Cloud Bigtable ou o BigQuery para armazenamento e análise.
Objetivos
Neste tutorial, confira como:
criar um App para iOS, o Playchat, que armazena dados no Firebase Realtime Database;
executar um servlet Java no ambiente flexível do App Engine que se conecta ao Firebase e recebe notificações quando os dados armazenados no Firebase são alterados;
usar esses dois componentes para criar um serviço de back-end de streaming distribuído para coleta e processamento de dados do log.
Custos
O Firebase tem um nível de uso gratuito. Não há cobrança quando o uso desses serviços é menor do que os limites especificados no plano gratuito do Firebase.
As instâncias do ambiente flexível do App Engine são cobradas pelo custo das máquinas virtuais subjacentes do Compute Engine.
Antes de começar
Instale os seguintes softwares:
- Git
- Xcode 9
- CocoaPods
- Apache Maven (em inglês) 3.6.x ou superior
- Java 8 ou superior
- Google Cloud CLI
Instale o componente Java do App Engine da CLI gcloud executando o seguinte comando em uma janela do terminal:
gcloud components install app-engine-java
Clonar o código de amostra
Clone o código do aplicativo cliente.
git clone https://github.com/GoogleCloudPlatform/firebase-ios-samples
Clone o código do servlet de back-end.
git clone https://github.com/GoogleCloudPlatform/firebase-appengine-backend
Como criar um projeto do Firebase
Clique em Adicionar projeto.
Em Nome do projeto, insira:
Playchat
. Anote o ID do projeto atribuído. Ele é usado em várias etapas neste tutorial.Siga as etapas de configuração restantes e clique em Criar projeto.
Após o assistente provisionar seu projeto, clique em Continuar.
Na página Visão geral do projeto, clique no símbolo de engrenagem para Configurações e em Configurações do projeto.
Clique em Adicionar o Firebase ao app para iOS.
Em ID do pacote do iOS, insira:
com.google.cloud.solutions.flexenv.PlayChat
.Clique em Registrar aplicativo.
Siga as etapas na seção Fazer o download do arquivo de configuração para adicionar o arquivo
GoogleService-Info.plist
à pastaPlayChat
no projeto.Clique em Avançar na seção Fazer download do arquivo de configuração.
Anote as instruções de uso do CocoaPods para instalar e gerenciar dependências do projeto. O gerenciador de dependências CocoaPods já está configurado no código da amostra.
Execute o comando a seguir para instalar as dependências: O comando pode levar muito tempo para ser concluído.
pod install
Talvez seja necessário executar
pod repo update
se a instalação do CocoaPods não conseguir encontrar a dependência do Firebase.Após esta etapa, use o arquivo
.xcworkspace
recém-criado em vez do arquivo.xcodeproj
para todo o desenvolvimento futuro no app para iOS.Clique em Próxima na seção Adicionar SDK do Firebase.
Anote o código necessário para inicializar o Firebase no projeto.
Clique em Avançar na seção Adicionar código de inicialização.
Clique em Pular etapa na seção Executar seu app para verificar a instalação.
Como criar um Realtime Database
No Console do Firebase, selecione seu projeto.
No menu à esquerda do console, selecione Realtime Database no grupo Build.
Clique em Criar banco de dados na seção Realtime Database.
Selecione um local próximo a você.
Na caixa de diálogo Regras de segurança, selecione Iniciar no modo de teste e clique em Ativar.
Nesse passo, os dados armazenados são exibidos no Firebase. Nas próximas etapas deste tutorial, revisite essa página da Web para ver os dados acrescentados e atualizados pelo aplicativo cliente e pelo servlet do back-end.
Na guia Regras do banco de dados, confirme se você tem as regras de segurança para leitura/gravação que especificam uma data 30 dias no futuro com a unidade de tempo definida em Horário Unix do período. Por exemplo, se você estiver criando a regra em 4 de agosto, ela deverá expirar após 4 de setembro:
{ "rules": { ".read": "now < 1659639249000", //2022-08-04 ".write": "now < 1659639249000" //2022-08-04 } }
Anote o URL do Firebase do seu projeto, que está no formato
https://[FIREBASE_PROJECT_ID].firebaseio.com/
e aparece ao lado de um ícone de link.
Ativar a autenticação do Google para o projeto do Firebase
Há vários provedores de login configurados para fazer a conexão com o projeto do Firebase. Neste tutorial, você aprende a configurar a autenticação para que o usuário faça o login usando uma Conta do Google.
No menu à esquerda do Console do Firebase, clique em Autenticação no grupo Desenvolver.
Clique em Configurar método de login ou Primeiros passos se for a primeira vez que você acessa a página.
Sob aMétodo de login guia, selecionar Google, selecione o botão Ativar, selecione o e-mail de suporte e clique em Salvar.
Adicionar uma conta de serviço ao projeto do Firebase
O login no servlet de back-end não é feito usando uma Conta do Google. Em vez disso, é usada uma conta de serviço para se conectar ao Firebase. Nas etapas a seguir é mostrado como criar uma conta de serviço para conectar-se com o Firebase e adicionar as credenciais dessa conta ao código do servlet.
No menu à esquerda do Console do Firebase, ao lado da página inicial do projeto do Playchat, selecione a engrenagem Configurações e clique em Configurações do projeto.
Selecione Contas de serviço e clique no link Gerenciar permissões de conta de serviço.
Clique em Criar conta de serviço.
Defina as configurações a seguir:
- Em Nome da conta de serviço, digite
playchat-servlet
e clique em Criar e continuar. Em Selecionar um papel, selecione Projeto > Proprietário e clique em Continuar.
Clique em Concluído.
- Em Nome da conta de serviço, digite
Clique na conta de serviço que você acabou de criar, na guia CHAVES, clique em Adicionar chave e, em seguida, clique em Criar nova chave.
Ao lado de Tipo de chave, clique em JSON e em Criar para fazer o download da chave.
Salve o arquivo de chave JSON baixado para a conta de serviço no projeto de serviço de back-end,
firebase-appengine-backend
, no diretóriosrc/main/webapp/WEB-INF/
. O nome de arquivo está no formatoPlaychat-[UNIQUE_ID].json
.Edite
src/main/webapp/WEB-INF/web.xml
e os parâmetros de inicialização da seguinte forma:Substitua
JSON_FILE_NAME
pelo nome do arquivo de chave JSON que você fez download.Substitua
FIREBASE_URL
pelo URL do Firebase anotado anteriormente.<init-param> <param-name>credential</param-name> <param-value>/WEB-INF/JSON_FILE_NAME</param-value> </init-param> <init-param> <param-name>databaseUrl</param-name> <param-value>FIREBASE_URL</param-value> </init-param>
Como ativar o faturamento e as APIs para o projeto do Google Cloud
Para que o serviço de back-end seja executado no GCP, você precisa ativar o faturamento e as APIs do projeto. O projeto do Cloud é o mesmo criado em Como criar um projeto do Firebase e tem o mesmo identificador de projeto.
No Console do Google Cloud, selecione o projeto Playchat.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the App Engine Admin and Compute Engine APIs.
Criar e implantar o serviço de back-end
Uma configuração do Docker é usada no serviço de back-end desta amostra para especificar o ambiente de hospedagem. Essa personalização significa que você precisa usar o ambiente flexível do App Engine, não o ambiente padrão.
Para criar o servlet de back-end e implantá-lo no ambiente flexível do App Engine, use o plug-in Maven do Google App Engine. Esse plug-in está especificado no arquivo de criação do Maven, incluído nesta amostra.
Configurar o projeto
Para que o servlet de back-end seja criado corretamente pelo Maven, forneça a ele o projeto do Google Cloud Platform (GCP) para ativar os recursos desse servlet. O identificador de projeto do GCP e o do Firebase são os mesmos.
Forneça as credenciais usadas pela CLI gcloud para acessar o GCP.
gcloud auth login
Defina o projeto do Firebase com o comando a seguir, substituindo [FIREBASE_PROJECT_ID] pelo nome do código do projeto anotado anteriormente.
gcloud config set project [FIREBASE_PROJECT_ID]
Para verificar se o projeto foi definido, liste a configuração.
gcloud config list
Se esta for a primeira vez que você está usando o App Engine, inicialize seu aplicativo do App Engine:
gcloud app create
(Opcional) Executar o serviço no servidor local
Ao desenvolver um novo serviço de back-end, execute o serviço localmente antes de implantá-lo no App Engine para repetir rapidamente as alterações sem a sobrecarga de uma implantação completa.
Quando o servidor é executado localmente, não é usada uma configuração Docker nem a execução em um ambiente do App Engine. Em vez disso, o Maven garante que todas as bibliotecas dependentes sejam instaladas localmente e o aplicativo seja executado no servidor da Web Jetty.
No diretório
firebase-appengine-backend
, crie e execute o módulo de back-end localmente com o comando a seguir:mvn clean package appengine:run
Se você instalou a Google Cloud CLI em um diretório diferente de
~/google-cloud-sdk
, adicione o caminho de instalação ao comando substituindo[PATH_TO_TOOL]
pelo caminho personalizado, como demonstrado a seguir.mvn clean package appengine:run -Dgcloud.gcloud_directory=[PATH_TO_TOOL]
Quando a pergunta Quer que o aplicativo "Python.app" aceite conexões de rede recebidas? for exibida, selecione Permitir.
Quando a implantação terminar, abra http://localhost:8080/printLogs para verificar se o serviço de back-end está sendo executado. Na página da Web, será exibida Caixa de entrada:, seguida por um identificador de 16 dígitos. Esse é o identificador da caixa de entrada para o servlet em execução na máquina local.
Quando você atualiza a página, esse identificador permanece inalterado. Seu servidor local ativa uma única instância de servlet. Isso é útil para testes, porque há apenas um identificador de servlet armazenado no Firebase Realtime Database.
Para encerrar o servidor local, digite Ctrl + C.
Implantar o serviço no ambiente flexível do App Engine
Quando o serviço de back-end é executado no ambiente flexível do App Engine, o app usa a configuração em /firebase-appengine-backend/src/main/webapp/Dockerfiles
para criar o ambiente de hospedagem em que o serviço é executado. Nesse ambiente, várias instâncias de servlet são geradas e escalonadas para atender à demanda.
No diretório
firebase-appengine-backend
, crie e execute o módulo de back-end localmente com o comando a seguir:mvn clean package appengine:deploy
mvn clean package appengine:deploy -Dgcloud.gcloud_directory=[PATH_TO_GCLOUD]
Durante a execução da compilação, aparece a mensagem “Enviando contexto de compilação para o daemon do Docker…”. O comando anterior faz o upload da configuração do Docker e a instala no ambiente flexível do App Engine.
Ao final da implantação, abra https://[FIREBASE_PROJECT_ID].appspot.com/printLogs
, em que [FIREBASE_PROJECT_ID]
é o identificador de Criar um projeto do Firebase. Na página da Web, será exibida Caixa de entrada:, seguida por um identificador de 16 dígitos. Esse é o identificador da caixa de entrada de um servlet em execução no ambiente flexível do App Engine.
Esse identificador muda periodicamente, à medida que a página é atualizada, porque o App Engine ativa diversas instâncias de servlet a fim de processar as solicitações de clientes recebidas.
Como atualizar o esquema de URL na amostra para iOS
No Xcode, com o espaço de trabalho
PlayChat
aberto, abra a pastaPlayChat
.Abra
GoogleService-Info.plist
e copie o valor deREVERSED_CLIENT_ID
.Abra
Info.plist
e navegue para tipos de URL de chave > Item 0 (Editor) > Esquemas de URL > Item 0.Substitua o valor do marcador, [REVERSED_CLIENT_ID], pelo valor copiado de
GoogleService-Info.plist
.
Como executar e testar o app para iOS
No Xcode, com o espaço de trabalho
PlayChat
aberto, selecione Product (Gerar) Run (Executar).Quando o aplicativo for carregado no simulador, faça login com sua Conta do Google.
Selecione o canal books.
Digite uma mensagem.
Quando você faz isso, o aplicativo Playchat armazena a mensagem no Firebase Realtime Database. Os dados armazenados no banco de dados do Firebase são sincronizados com todos os dispositivos. Quando o Playchat é executado nesses dispositivos, a nova mensagem é exibida assim que o usuário seleciona o canal books.
Verificar os dados
Depois de usar o aplicativo Playchat para gerar alguns eventos do usuário, verifique se os servlets estão sendo registrados como listeners e coletando logs de eventos de usuários.
Abra o Firebase Realtime Database do aplicativo, em que [FIREBASE_PROJECT_ID]
é o identificador de Criar um projeto do Firebase.
https://console.firebase.google.com/project/[FIREBASE_PROJECT_ID]/database/data
No parte inferior do Firebase Realtime Database, no local de dados /inbox/
, há um grupo de nós prefixados por client-
e seguidos por uma chave gerada aleatoriamente que representa o login da conta do usuário. A última entrada neste exemplo, client-1240563753
, é seguida por um identificador de 16 dígitos do servlet que está detectando os eventos de registro do usuário neste exemplo 0035806813827987
.
Logo acima, no local de dados /inbox/
, estão os identificadores servlet de todos os servlets atribuídos no momento. Neste exemplo, os logs são coletados por apenas um servlet. Os registros de usuário gravados pelo app para esse servlet estão em /inbox/[SERVLET_IDENTIFIER]
.
Abra a página do App Engine para seu serviço de back-end em https://[FIREBASE_PROJECT_ID].appspot.com/printLogs
, em que [FIREBASE_PROJECT_ID]
é o identificador de Como criar um projeto do Firebase. O identificador do servlet que registrou os eventos do usuário gerados por você é exibido na página. É possível também ver as entradas de registros para os eventos abaixo do identificador da caixa de entrada do servlet.
Como explorar o código
No app Playchat para iOS, a classe FirebaseLogger
é definida
para gravar registros de eventos do usuário no Firebase Realtime Database.
Quando um novo usuário faz login, o Playchat chama a função requestLogger
para adicionar uma nova entrada ao local /requestLogger/
no Firebase Realtime Database e definir um listener. Dessa forma, o Playchat poderá responder quando um servlet atualizar o valor dessa entrada, aceitando a atribuição.
Quando um servlet atualiza o valor, o Playchat remove o listener e grava o registro como "Conectado" na caixa de entrada do servlet.
Quando uma instância de servlet é iniciada no lado do serviço de back-end, a função init(ServletConfig config)
em MessageProcessorServlet.java
se conecta ao Firebase Realtime Database e adiciona um listener ao local de dados /inbox/
.
Quando uma nova entrada é adicionada ao local de dados /inbox/
, o servlet atualiza o valor com seu identificador. Isso sinaliza para o app Playchat que o servlet aceita a atribuição para processar registros para esse usuário. As transações do Firebase são usadas para garantir que somente um servlet possa atualizar o valor e aceitar a atribuição.
Depois de uma tarefa de processar os logs de eventos de um usuário ser aceita pelo servlet, um listener é adicionado. Esse listener detecta quando um novo arquivo de log é gravado na caixa de entrada pelo aplicativo Playchat. A resposta do servlet é recuperar os novos dados de log do Firebase Realtime Database.
Limpeza
Para evitar que os recursos usados nesse tutorial sejam cobrados na sua conta do Google Cloud Platform:Excluir o projeto do Google Cloud Platform e do Firebase
A maneira mais simples de não ser cobrado é excluir o projeto criado neste tutorial. Embora você tenha criado o projeto no Console do Firebase, também é possível excluí-lo no Console do Google Cloud, porque os projetos do Firebase e do Cloud são os mesmos.
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Excluir as versões não padrão do aplicativo App Engine
Se você não quiser excluir o projeto do GCP e do Firebase, uma alternativa é excluir as versões não padrão do aplicativo de ambiente flexível do App Engine para reduzir custos.
- In the Google Cloud console, go to the Versions page for App Engine.
- Select the checkbox for the non-default app version that you want to delete.
- Para excluir a versão do app, clique em Excluir.
A seguir
Analisar e arquivar dados: neste exemplo, os dados do log são armazenados apenas na memória pelos servlets. Para ampliar essa amostra, use os servlets para arquivar, transformar e analisar os dados, com serviços como o Cloud Storage, o Cloud Bigtable, o Google Cloud Dataflow e o BigQuery.
Distribuir uniformemente a carga de trabalho entre os servlets: no App Engine, você tem escalonamento automático e manual. Com o escalonamento automático, as alterações são detectadas no ambiente flexível, que responde adicionando ou removendo instâncias de VMs no cluster. Com o escalonamento manual, você especifica um número estático de VMs para processar o tráfego. Para mais informações sobre como configurar o escalonamento, consulte Configurações de escalonamento de serviço na documentação do App Engine.
Como os logs de atividade do usuário são atribuídos aos servlets por meio do acesso ao Firebase Realtime Database, a carga de trabalho pode não ser distribuída uniformemente. Por exemplo, um servlet pode processar mais logs de eventos de usuários do que outros.
Para melhorar a eficiência, implemente um gerenciador para controlar de maneira independente a carga de trabalho de cada VM. Esse balanceamento de carga pode basear-se em métricas como, por exemplo, as solicitações de geração de registros por segundo ou o número de clientes simultâneos.
Recuperar logs de eventos de usuários não processados: nessa implementação de amostra, quando ocorre uma falha em uma instância de servlet, o aplicativo cliente associado a ela continua a enviar eventos de registros para a caixa de entrada do servlet no Firebase Realtime Database. Em uma versão de produção desse aplicativo, é necessário que o serviço de back-end identifique a situação para recuperar os registros de eventos de usuários não processados.
Implemente recursos extras usando produtos do Cloud AI: explore como fornecer recursos baseados em ML com produtos e serviços do Cloud AI. Por exemplo, amplie essa implementação de amostra para fornecer um recurso de tradução de fala usando uma combinação das APIs Speech-to-Text, Translation e Text-to-Speech. Para mais informações, consulte Como adicionar tradução de fala ao seu app para Android.