Neste codelab, você vai aprender como usar o <firebase-element> para armazenar e processar seus dados usando Firebase.

O que você irá aprender?

Do que você precisa

Como você classifica sua experiência com Polymer?

Básica Intermediária Avançada

Criando um novo projeto

A primeira vez que você executar o Chrome Dev Editor ele irá pedir para configurar o seu ambiente de trabalho.

Abra o Chrome Dev Editor e inicie um novo projeto

  1. Clique no botão para iniciar um novo projeto.
  2. Preencha "PolymerFirebaseCodelab" como o nome do Projeto.
  3. Na caixa de seleção Tipo de Projeto, selecione "JavaScript web app (usando Polymer paper elements)".
  4. Clique no botão Criar.

Chrome Dev Editor cria uma estrutura básica para seu aplicativo Polymer. Em background, também usa o Bower para fazer download e instalar uma lista de dependências (incluindo a biblioteca principal do Polymer) na pasta bower_components/. Fazer o download dos componentes pode demorar se sua conexão com a internet é lenta. Você irá aprender mais sobre como utilizar o Bower no próximo passo.

Se em algum momento você ficar confuso, você pode analisar o código completo para cada passo individualmente no repositório do GitHub para este codelab.

Visualizando o app

A qualquer momento, selecione o arquivo index.html e aperte o botão na barra de ferramentas superior para executar o aplicativo. O Chrome Dev Editor inicia um servidor web e navega para a página index.html. Esta é uma ótima maneira de visualizar as alterações que você fizer.

Primeiro você aprenderá como criar um TODO app com Polymer sem persistência e então adicionará a parte de persistência utilizando o Firebase.

Preparando os componentes de interface

Primeiro, importe o componente paper-elements para que você possa aceitar entradas de dados do usuário.

No <head> do arquivo index.html existe uma lista de arquivos que já foram importados. Adicione o import no trecho de código abaixo no final da lista.

index.html

<head>
  ...
  <link rel="import" href="bower_components/paper-input/paper-input.html">
  ...
</head>

Construindo a UI

Você irá adicionar o elemento <form> contendo um componente <paper-input> e um <paper-button> na parte superior. O formulário dispara um evento de submit quando a tecla Enter é pressionada sem a necessidade de você escrever qualquer código adicional. Logo abaixo, você utilizará o elemento <template is="dom-repeat"> para percorrer a lista com os itens e criar um checkbox e um botão de exclusão para cada item.

Altere o conteúdo da tag <body> do arquivo index.html para que fique igual ao código abaixo:

index.html

<body unresolved>
  <template is="dom-bind" id="app">
    <form on-submit="addItem">
      <paper-input value="{{newItemValue}}" 
        placeholder="O que você precisa fazer..."></paper-input>
      <paper-button on-click="addItem">Adicionar</paper-button>
    </form>
    <template is="dom-repeat" items="{{items}}">
      <div>
        <paper-icon-button icon="delete" 
          on-click="deleteItem"></paper-icon-button>
        <paper-checkbox on-change="toggleItem"
          checked="{{item.done}}">[[item.text]]</paper-checkbox>
      </div>
    </template>
  </template>
  <script src="main.js"></script>
</body>

Esse codelab não é sobre estilos, portanto basta substituir o conteúdo do arquivo style.css com os estilos abaixo:

style.css

body {
  font-family: Roboto, sans-serif;
  color: #333;
  max-width: 700px;
  width: 100%;
  margin: 0 auto;
}

form {
  display: flex;
  flex-direction: row;
  align-items: center;
  margin-bottom: 20px;
}

paper-button {
  flex-shrink: 1;
}
paper-input {
  flex-grow: 1;
}

paper-checkbox {
  display: inline-block;
  margin: 5px 0;
  transition: opacity 0.3s;
}

paper-checkbox[checked] {
  opacity: 0.5;
}

Adicionando a lógica

Como você já percebeu a partir do markup, teremos uma lista chamada items, e cada item é um objeto que fornece um elemento done e um campo text.

Além disso, teremos uma função chamada addItem que será invocada quando o usuário pressionar a tecla Enter dentro do componente <paper-input> ou clicar no botão "Adicionar". Você também precisará criar uma função chamada toggleItem que alterna o estado de concluído de um item da lista e por fim uma função chamada deleteItem que remove um item da lista.

Abra o arquivo main.js e altere o seu contéudo usando o código abaixo.

main.js

(function(document) {
  'use strict';

  var app = document.querySelector('#app');
  
})(document);

Com a variável app você agora tem a referência para o elemento <template is="dom-bind"> em seu markup. Agora você precisa adicionar valores e métodos a ele, começando com sua lista de itens. Logo abaixo da declaração da variável app adicione o seguinte código.

main.js

app.items = [
  {
    done: true,
    text: 'Construir um TODO app'
  },
  {
    done: false,
    text: 'Usar Firebase'
  }
];

Esses dois itens são apenas para demonstração, dessa forma você consegue ver que os estados de checked e unchecked estão funcionando corretamente.

Logo abaixo, continue adicionando três métodos usando as funções utilitárias do Polymer. Elas são equivalentes à suas partes nativas, mas também cuidam de emitir eventos com as alterações, se necessário, para atualizar qualquer binding daquela variável. Para mais detalhes, consulte a documentação do <template is="dom-repeat">.

main.js

app.addItem = function(event) {
  event.preventDefault(); // Don't send the form!
  this.push('items', {
    done: false,
    text: app.newItemValue
  });
  this.newItemValue = '';
};

app.toggleItem = function(event) {
  event.model.set('done', !event.model.item.done);
};
app.deleteItem = function(event) {
  this.splice('items', event.model.index, 1);
};

event.model em toggleItem é uma propriedade definida pelo <template is="dom-repeat"> que provê aos event handlers uma forma de acessar os dados utilizados naquela interação da repetição.

Apenas um lembrete: Se você quiser, você pode dar uma olhada no resultado pressionando .

Próximo passo

Agora você já tem a lógica, mas sem persistência. Vamos ao Firebase.

Agora é hora de utilizar o <firebase-element>!

Criando uma instância do Firebase

  1. Acesse https://www.firebase.com
  2. Crie uma conta. Você pode clicar em "Sign up" e criar uma nova conta ou clique em "Login" e utilize sua conta do Google para fazer login.
  3. No painel crie um novo aplicativo Firebase. Você terá que escolher uma URL diferente da que está sendo mostrada na imagem.

  1. Clique na URL do aplicativo recém-criado para abrir o painel e ver o banco de dados vazio.

Permitindo acesso anônimo

Por enquanto, você vai permitir logins anônimos para a sua aplicação. Abra o painel da aplicação do Firebase que você acabou de criar na etapa anterior, vá para a aba "Login & Auth" e ative a opção de login anônimo.

Adicionando os componentes do Firebase

Agora você tem um app Firebase à sua disposição. Para realmente fazer uso dele, você precisa adicionar o elemento Firebase correspondente. Abra o arquivo bower.json e adicione o componente firebase-element à lista de dependências. As dependências devem ficar assim:

bower.json

"dependencies": {
  "iron-elements": "PolymerElements/iron-elements#^1.0.0",
  "paper-elements": "PolymerElements/paper-elements#^1.0.1",
  "firebase-element": "PolymerElements/firebase-element#^1.0.0"
}

Depois, clique com o botão direito na pasta bower_components e clique em "Bower Install". O Chrome Dev Editor fará o download e irá instalar todas as dependências para você.

Adicione as seguintes linhas no seu markup:

index.html

<link rel="import" href="bower_components/firebase-element/firebase-auth.html">
<link rel="import" href="bower_components/firebase-element/firebase.html">

Agora vamos armazenar em variavéis o método de autenticação e sua URL do Firebase. Adicione o seguinte código diretamente abaixo de sua declaração da variável app:

main.js

app.firebaseURL = 'https://<YOUR FIREBASE NAME>.firebaseio.com';
app.firebaseProvider = 'anonymous';

Lembre-se de ajustar a URL de acordo com a que foi configurada no Firebase.

Para autenticar o usuário, você irá usar o elemento <firebase-auth>. Para simplificar, você não permitirá que seu aplicativo possa ser usado sem identificação. Portanto, você pode imediatamente disparar o processo de login após o carregamento da página, o elemento fornece um atributo auto-login para isso.

No topo de nosso <template> adicione:

index.html

<firebase-auth
  auto-login
  redirect
  location="[[firebaseURL]]"
  provider="[[firebaseProvider]]"
  on-error="onFirebaseError"
  on-login="onFirebaseLogin"></firebase-auth>
<paper-toast id="errorToast"></paper-toast>

Agora você irá utilizar o <paper-toast> para exibir os erros que podem ocorrer durante o processo de autenticação. Você será notificado de tais erros pelo handler onFirebaseError que você já adicionou. Se o login for bem-sucedido, onFirebaseLogin será disparado. Você irá utilizar essa oportunidade para detectar as alterações no elemento Firebase.

Adicione essas duas funções no fim do arquivo main.js:

main.js

app.onFirebaseError = function(event) {
  this.$.errorToast.text = event.detail.message;
  this.$.errorToast.show();
};
app.onFirebaseLogin = function(event) {
  this.ref = new Firebase(this.firebaseURL + '/user/' + 
                                                event.detail.user.uid);
};

Próximo passo

Você tem tudo o que precisa para acessar a base de dados do Firebase. Agora você vai realmente utilizar o banco de dados.

Agora que a autenticação está configurada, você tem acesso à base de dados dos usuários. Adicione um event handler à sua referência do objeto Firebase para ser notificado sempre que alterações nos dados acontecerem.

Modifique seu handler onFirebaseLogin com o código abaixo:

main.js

app.onFirebaseLogin = function(event) {
  this.ref = new Firebase(this.firebaseURL + '/user/' + 
                                                  event.detail.user.uid);
  this.ref.on('value', function(snapshot) {
    app.updateItems(snapshot);
  });
};

Agora você irá sincronizar com o Firebase imediatamente, então remova os dados que você adicionou para demonstração no início do codelab.

  1. Substitua os dados fictícios em app.items com um array vazio
  2. Adicione a implementação do método updateItems.

O evento value do Firebase passa uma instância dos novos dados no parâmetro snapshot. Já que nós sabemos que os dados do usuário é um array de itens, nós vamos iterar sobre eles e adicionar cada um a nossa lista items. No final, o código deve ser semelhante a este:

app.js

app.items = [];

app.updateItems = function(snapshot) {
  this.items = [];
  snapshot.forEach(function(childSnapshot) {
    var item = childSnapshot.val();
    item.uid = childSnapshot.key();
    this.push('items', item);
  }.bind(this));
};

Agora você precisa atualizar seus três event handlers para usar o Firebase e o uid ("identificador único") de cada item. Observe que você está usando o método push()do Firebase e não o do Polymer. Os novos dados serão adicionados à sua instância do Firebase. O handler updateItems() vai cuidar de manter a cópia local atualizada.

main.js

app.addItem = function(event) {
  event.preventDefault(); // Don't send the form!
  this.ref.push({
    done: false,
    text: app.newItemValue
  });
  app.newItemValue = '';
};

app.toggleItem = function(event) {
  this.ref.
    child(event.model.item.uid).
    update({done: event.model.item.done});
};

app.deleteItem = function(event) {
  this.ref.child(event.model.item.uid).remove();
};

Pressione o botão e veja o Firebase em ação. Adicione itens, marque-os como concluídos e remova items. Depois disso, recarregue a página e veja que seus itens não se perderam no limbo.

Próximo Passo

Você já tem uma prova de conceito, mas para entregar um produto mínimo viável você precisa adicionar algumas coisas, começando com segurança.

Atualmente a sua lista de TODO não está segura. Se alguém descobrir seu uid, ele apena precisará abrir o DevTools e acessar seus dados. As "Regras de Segurança" do Firebase resolvem esse problema. Para restringir o acesso à documentos apenas para aquele usuário, siga os seguintes passos:

  1. Acesse o painel de sua conta do Firebase
  2. Navegue para a sessão "Security & Rules"
  3. Mude as regras conforme o snippet abaixo:

Security & Rules

{
    "rules": {
        "user": {
          "$uid": {
            ".read": "auth != null && auth.uid == $uid",
            ".write": "auth != null && auth.uid == $uid"
          }
        }
    }
}

Esta regra garante que usuários só terão permissão de leitura e escrita para os seus próprios dados. Modificando o uid no DevTools irá resultar em erro.

Próximo passo

Neste último passo, você irá permitir a autenticação através do Google para que os usuários possa acessar suas listas de todos os seus devices.

Atualmente o seu aplicativo está diretamente ligado à instância do navegador (o uid anônimo é guardado usando o local storage), os usuários só podem acessar suas listas a partir da máquina onde estas foram criadas. Para mudar isso, você precisa usar um uid consistente entre vários dispositivos. Usar o Google login é uma maneira de conseguir isso.

Obtendo uma Google API Key

Para utilizar o Google Login, você precisa criar uma API key. Acesse o Google Developer Console e crie um novo projeto. Uma vez que o projeto foi criado, acesse "APIs & auth" → "Credentials" e crie um novo "OAuth 2.0 client ID".

Selecione "Web Application". Se o assistente não permitir, siga as instruções na tela. Em seguida, adicione a url https://auth.firebase.com na sessão Authorized JavaScript origins e insira a url https://auth.firebase.com/v2/<your Firebase ID>/auth/google/callback na sessão Authorized redirect URIs:

Clique em "Criar". Seu Client ID e Client Secret serão mostrados na tela. Salve-os para o próximo passo.

Ativando autenticação com o Google!

Navegue de volta para o painel do seu aplicativo no Firebase, vá para sessão "Login & Auth", em seguida para a aba "Google" e informe as credenciais que você acabou de salvar na etapa anterior.

Seu aplicativo agora suporta autenticação usando as credenciais do Google. A única coisa que falta é informar ao seu app que ele suporta autenticação com o Google. Altere a variável firebaseProvider para google:

main.js

app.firebaseProvider = 'google';

Aqui é onde pressionar o botão fica realmente divertido! Abra vários navegadores, faça o login com sua conta do Google, se você não tiver feito isso ainda, e veja sua lista sendo sincronizada com todos os navegadores em tempo real! Você também pode abrir uma janela anônima se você quiser ver novamente o processo de autenticação.

Você acabou de construir um TODO app que pode ser utilizado em paralelo em vários dispositivos. Mágica do Firebase!

O que você aprendeu

Aprenda mais

Polymer

Outros