Como criar um aplicativo de pesquisa Vue usando autenticação e banco de dados do Firebase
Como criar um aplicativo de pesquisa Vue usando autenticação e banco de dados do Firebase
Publicados: 2022-03-10
Resumo rápido ↬ Este tutorial mostra um guia passo a passo para criar um aplicativo de pesquisa funcional usando Vue.js e Firebase. Desde a validação dos dados do usuário através do Vuelidate, até a autenticação, armazenamento dos dados do usuário, proteção de rotas e envio de dados para servidores Firebase. Todos os passos usados no tutorial são práticos e podem ser reproduzidos em qualquer projeto da vida real, mesmo com um backend customizado.
Neste tutorial, você construirá um aplicativo de pesquisa, onde aprenderemos a validar os dados do formulário de nossos usuários, implementar a autenticação em Vue e receber dados de pesquisa usando Vue e Firebase (uma plataforma BaaS).
À medida que construímos este aplicativo, aprenderemos a lidar com a validação de formulários para diferentes tipos de dados, incluindo entrar em contato com o back-end para verificar se um e-mail já foi recebido, mesmo antes de o usuário enviar o formulário durante a inscrição.
Além disso, o aplicativo lidaria com o login do usuário com APIs de descanso. Ele usará o Authguard no roteador Vue para impedir que usuários não logados obtenham acesso ao formulário de pesquisa e enviem com sucesso os dados de pesquisa de usuários logados para um banco de dados seguro.
Para estarmos na mesma página, vamos esclarecer o que é o Firebase e o que ele fará neste tutorial. O Firebase é um conjunto de ferramentas para “criar, melhorar e expandir seu aplicativo”, ele dá acesso a uma grande parte dos serviços que os desenvolvedores normalmente teriam que construir sozinhos, mas não querem construir porque preferem concentre-se na experiência do aplicativo em si. Isso inclui coisas como análise, autenticação, bancos de dados, armazenamento de arquivos e a lista continua.
Isso é diferente do desenvolvimento tradicional de aplicativos, que normalmente envolve escrever software de front-end e back-end. O código de front-end apenas invoca os endpoints da API expostos pelo back-end, e o código de back-end realmente faz o trabalho. No entanto, com os produtos Firebase, o back-end tradicional é ignorado, colocando o trabalho no cliente. Isso tecnicamente permite que engenheiros de front-end como eu construam aplicativos full-stack escrevendo apenas código de front-end.
Mais depois do salto!Continue lendo abaixo ↓
A conclusão é que o Firebase atuaria como nosso back-end neste projeto, fornecendo-nos os endpoints de API necessários para lidar com nossas necessidades de autenticação e banco de dados. No final, você terá construído um aplicativo de pesquisa funcional usando Vue+ Firebase. Depois disso, você pode criar qualquer aplicativo da Web de sua escolha usando esses mesmos processos, mesmo com um back-end personalizado.
Para acompanhar, você precisa ter o Node e o npm/yarn instalados em sua máquina. Se você ainda não fez isso, siga estes guias rápidos para instalar o yarn ou o npm em sua máquina. Você também precisa ter um entendimento básico da sintaxe do roteador Vue, Vuex e Vue para este tutorial.
Os arquivos iniciais para este tutorial estão aqui, que contém os arquivos base para este projeto, e aqui está o repositório para a demonstração concluída. Você pode clonar ou baixar os repositórios e executar npm install em seu terminal.
Depois de instalar o arquivo inicial, você verá uma página de boas-vindas, que tem as opções para se inscrever e fazer login. Depois de fazer login, você poderá acessar a pesquisa.
Sinta-se à vontade para criar um novo projeto se quiser construir este projeto inteiramente por conta própria, apenas certifique-se de instalar Vuex, roteador Vue, Vuelidate e axios em seu projeto Vue. Então vamos pular direto:
Primeiro, precisaremos de uma conta do Firebase para configurar este projeto, que é muito parecido com criar um contêiner para nosso aplicativo, nos dando acesso ao banco de dados, vários meios de autenticação, hospedagem etc. É fácil configurar assim que você estão no site do Firebase.
Agora que temos nosso projeto, o próximo passo é configurar nosso sistema de autenticação e banco de dados (banco de dados em tempo real) no Firebase.
Clique na opção “autenticação”;
Configure o “método de login” que queremos (neste caso, email/senha).
Clique em “banco de dados”.
Escolha “Banco de dados em tempo real” e copie este link que está logo acima.
Será muito útil como endpoint da API quando quisermos enviar os dados para nosso banco de dados do Firebase.
Vamos nos referir a essa API como a API do banco de dados. Para usá-lo, você terá que adicionar o nome do banco de dados de sua escolha ao enviá-lo. Por exemplo, para enviar para um banco de dados chamado user. Você simplesmente adiciona user.json no final:
{databaseAPI}/user.json
Depois disso, acessaremos a documentação da API Firebase auth rest para fazer nossa inscrição e fazer login nos endpoints da API. Dentro desses endpoints, haverá a necessidade da chave de API do nosso projeto, que pode ser encontrada nas configurações do nosso projeto.
Validação
Voltando ao nosso código, haverá uma validação dos dados de cadastro antes de serem enviados ao servidor, apenas para garantir que o usuário esteja enviando as informações apropriadas. Estaremos usando o Vuelidate, que é uma biblioteca legal que facilita a validação no Vue. Antes de tudo, instale o Vuelidate no projeto:
npm i vuelidate
Vá para src/components/auth/signup.vue e dentro da tag script import vuelidate e todos os eventos necessários que precisaremos da biblioteca como visto abaixo.
Observação : você pode verificar os documentos para obter uma visão geral completa da biblioteca e de todos os eventos disponíveis.
Usado para comparar entre dois valores para garantir que eles sejam os mesmos
Importe também [`axios`](https://github.com/axios/axios) para poder enviar uma solicitação HTTP para o servidor:
import axios from 'axios'
Antes de prosseguirmos, precisaremos adicionar algumas regras ao banco de dados para podermos validar o email como deveríamos, conforme visto abaixo:
"read" = "true"
O que significa que o banco de dados pode ser lido sem qualquer impedimento do lado do cliente.
"write" = "auth" !== null
Você não pode escrever no banco de dados, exceto se for um usuário autenticado.
"Users" = { "onIndex" : ["email"] }
Isso nos permite consultar o documento `users` com um índice de `email`. Ou seja, você pode literalmente filtrar o banco de dados para um e-mail exclusivo. Em seguida, adicione uma propriedade computada personalizada com o nome `validations` assim como temos métodos, computados, etc. Em `validations` teremos métodos para validar os dados necessários a partir de `email` onde é obrigatório e obviamente deve ser um email . Além disso, queremos ser capazes de dizer a um usuário quando um email já foi recebido por outra pessoa, verificando o banco de dados após o usuário digitá-lo usando algo chamado validadores assíncronos, tudo dentro de um validador personalizado e tudo suportado por [vuelidate. ](https://vuelidate.js.org/#sub-asynchronous-validation)
Em seguida, em unique, consulte o banco de dados usando axios e use o Object.keys padrão para retornar a resposta apenas se seu comprimento for 0. Para a idade, você adicionará um valor obrigatório, numérico e um valor mínimo de 18 que é atribuído a `minVal ` como suas propriedades.
age: { required, numeric, minVal: minValue(18) }
As propriedades da senha são obrigatórias, com um comprimento mínimo de 6 atribuído a `minLen`.
password: { required, minLen: minLength(6) }
As propriedades `confirmPassword` são basicamente as mesmas que a senha.
Para informar ao usuário que o e-mail foi recebido, use `v-if` para verificar se `unique` é verdadeiro ou falso. Se true, significa que o comprimento do objeto retornado é 0, e o email ainda pode ser usado e vice-versa. Da mesma forma, você pode verificar se a entrada do usuário é um e-mail real usando `v-if`. E para todos os divs circundantes na entrada individual, adicionaremos uma classe de invalid que se tornará ativa quando houver um erro nessa entrada. Para vincular os eventos de validação a cada entrada no HTML, usamos [`$touch()`](https://vuelidate.js.org/#sub-without-v-model) como visto com o `email ` abaixo.
<div class="input" :class="{invalid: $v.email.$error}"> <h6 v-if="!$v.email.email">Please provide a valid email address.</h6> <h6 v-if="!$v.email.unique">This email address has been taken.</h6> <input type="email" placeholder="Email" @blur="$v.email.$touch()" v-model="email"> </div>
`Age`, `password` e `confirmPassword` serão vinculados à sua entrada HTML de maneira semelhante ao `email`. E tornaremos o botão 'Enviar' inativo se houver um erro em qualquer uma das entradas.
Aqui está um [exemplo CodePen](https://codepen.io/atanda1/pen/Yzyqrjv) completo para esta seção vuelidate. ## Autenticação Este aplicativo é um SPA e não recarrega como sites tradicionais, então usaremos Vuex, como nossa única "fonte de verdade" para permitir que todos os componentes em nosso aplicativo estejam cientes do status geral de autenticação. Vamos para o nosso arquivo de armazenamento e criamos o método de login/inscrição nas ações. As respostas (`token` e `userId`) recebidas quando enviamos os dados dos usuários, serão armazenadas dentro do nosso estado. Isso é importante porque o token será usado para saber se ainda estamos logados ou não em algum ponto do nosso aplicativo. O `token`, `userId` e o usuário são criados no estado com um valor inicial nulo. Chegaremos ao usuário muito mais tarde, mas, por enquanto, vamos nos concentrar nos dois primeiros.
Para inscrição/login, teremos que criar ações individuais para ambos, onde enviamos nossas solicitações de autenticação para o servidor. Depois disso, nossa resposta (token e userId) de inscrição/login é confirmada para authUser e salva no armazenamento local.
Mas aqui está a parte complicada, o que faremos com a ação de inscrição em particular é enviar apenas o e-mail e a senha para serem registrados no banco de dados de autenticação. Na verdade, não temos acesso para usar os dados desse banco de dados de autenticação e não enviamos nenhum de nossos dados de inscrição além de e-mail/senha. Então, o que faremos é criar outra ação para enviar os dados de inscrição completos para outro banco de dados. Neste documento de banco de dados separado, teremos acesso completo a todas as informações que escolhermos salvar lá. Chamaremos essa nova ação de `storeUser`. Então vamos para nossa ação de inscrição e despachamos todo o objeto contendo nossos dados de inscrição para um banco de dados ao qual agora temos acesso através de `storeUser`. **Nota:** Você pode não querer enviar a senha do seu usuário com `storeUser` para o banco de dados por motivos de segurança.
`storeUser` adiciona uma consulta usando nosso token recém-obtido e a API do banco de dados ao postar no banco de dados. Isso ocorre porque não podemos gravar em nosso banco de dados, exceto que somos autenticados com nossa prova (o token). Essa é a regra que demos ao Firebase no início, lembra?
“write” = “auth” !== null
O código completo para ações de inscrição/entrada está aqui [aqui](https://codepen.io/atanda1/pen/mdePKqj). Em seguida, envie a inscrição e o login de seus componentes no método `onSubmit` para as respectivas ações na loja.
## AuthGuard É necessário que o AuthGuard impeça que usuários não logados tenham acesso ao painel para onde enviarão a pesquisa. Acesse o arquivo de rotas e importe nossa loja.
import store from './store'
Dentro da rota, vá para o caminho do painel e adicione o seguinte:
Tudo o que isso faz é verificar se há um token no estado, se sim, damos acesso ao painel e vice-versa. ## LogOut Para criar nossa opção de logout, usaremos o `clearAuth` que criamos anteriormente em `mutations` que apenas configura o `token` e o `userId` para `null`. Agora criamos um novo `logout` `action` , que se compromete com `clearAuth`, exclui o armazenamento local e adiciona `router.replace('/')` para redirecionar o usuário completamente.
Em seguida, adicionamos um `@click` ao botão que dispara o método `onLogout` como podemos ver [aqui](https://codepen.io/atanda1/pen/jObqKNd).
<ul @click="onLogout">Log Out</ul>
## UI_State Agora que concedemos acesso condicional ao painel, a próxima etapa é removê-lo da barra de navegação, para que apenas usuários autenticados possam visualizá-lo. Para fazer isso, adicionaríamos um novo método nos `getters` chamado `ifAuthenticated` que verifica se o token dentro do nosso estado é nulo. Quando há um token, ele mostra que o usuário está autenticado e queremos que ele veja a opção do painel de pesquisa na barra de navegação.
Depois disso, você volta para o componente de cabeçalho e cria um método `auth` em computado, que despacha para nosso `isAuthenticated` dentro dos `getters` que acabamos de criar na loja. O que isso faz é que `isAuthenticated` retornaria false se não houvesse token, o que significa que `auth` também seria nulo e vice-versa.
Depois disso, adicionamos um `v-if` ao nosso HTML para verificar se `auth` é nulo ou não, determinando se essa opção seria exibida na barra de navegação.
- Você encontrará o código completo da seção UI State [aqui](https://codepen.io/atanda1/pen/QWjNxyo).
Login automático
Quando recarregamos nosso aplicativo, perdemos os dados e somos desconectados, tendo que começar tudo de novo. Isso ocorre porque nosso token e Id são armazenados em Vuex, que é javascript, e isso significa que nosso aplicativo é recarregado com o navegador quando atualizado.
E então, finalmente, o que faremos é recuperar o token em nosso armazenamento local. Ao fazer isso, podemos ter o token do usuário no navegador, independentemente de quando atualizarmos a janela, e ter um método de login automático de nosso usuário, desde que o token ainda seja válido.
Um novo método de actions chamado AutoLogin é criado, onde obteremos o token e o userId do armazenamento local e enviaremos nossos dados para o método authUser nas mutações.
Em seguida, vamos ao nosso App.vue e escrevemos um método created , que despachará o autoLogin de nossa loja toda vez que o aplicativo for carregado.
created () { this.$store.dispatch('AutoLogin') }
Buscar_User_Data
Queremos dar as boas-vindas ao usuário no painel exibindo o nome do usuário. E assim, outra ação chamada fetchUser é criada, que primeiro verifica se há um token como de costume. Em seguida, ele obtém o email do armazenamento local e consulta o banco de dados conforme feito anteriormente com a validação do email.
Isso retorna um objeto contendo os dados do usuário inicialmente enviados durante a inscrição. Em seguida, convertemos esse objeto em um array e o comprometemos com a mutação storeUser inicialmente criada.
De volta ao painel, criamos um novo método computado chamado name que retorna state.user.name somente se o usuário existir.
computed: { name () { return !this.$store.getters.user ? false : this.$store.getters.user.name } }, created () { this.$store.dispatch('fetchUser') } }
E também adicionaremos a propriedade computada created para despachar a ação fetchUser assim que a página for carregada. Em seguida, usamos o v-if em nosso HTML para exibir o nome se o nome existir.
<p v-if="name">Welcome, {{ name }} </p>
Send_Survey
Para enviar a pesquisa, criaremos uma ação postData que envia os dados para o banco de dados usando a API do banco de dados, com o token para mostrar ao servidor que o usuário está logado.
Aí está, temos muitos recursos úteis implementados em nosso aplicativo de demonstração enquanto nos comunicamos com nosso servidor Firebase. Espero que você use esses recursos poderosos em seu próximo projeto, pois eles são muito críticos para a criação de aplicativos da Web modernos hoje.
Se você tiver alguma dúvida, pode deixá-las na seção de comentários e terei prazer em responder a cada uma delas!
A demonstração do tutorial está disponível aqui.
Outros recursos que podem ser úteis incluem:
Para entender mais sobre o Firebase e os outros serviços que ele oferece, confira o artigo de Chris Esplin, “O que é Firebase?”
Vuelidate é uma biblioteca muito legal na qual você deveria se aprofundar. Você deve ler sua documentação para obter uma visão completa.https://vuelidate.js.org/.
Você também pode explorar axios por conta própria, especialmente se quiser usá-lo em projetos maiores.