Estruturar o banco de dados

Antes de começar

Para usar o Firebase Realtime Database, você precisa criar um projeto do Firebase e adicionar os pacotes do SDK para Unity do Firebase ao projeto do Unity.

Configuração:

Pré-requisitos

Android

  • Unity 5.0 ou posterior
  • Android NDK versão 10d ou posterior

iOS

  • Unity 5.0 ou posterior
  • Xcode 8.0 ou posterior

Se você ainda não tem um projeto do Unity, faça o download de um dos nossos exemplos de guia de início rápido e teste um recurso específico do Firebase. Nesse caso, anote o identificador do pacote nas configurações do projeto. Ele será necessário na próxima etapa.

Configurar seu app no Console do Firebase

Para adicionar o Firebase ao seu app, você precisa de um projeto e de um arquivo de configuração do Firebase.

Para criar um projeto do Firebase:

  1. Vá para o Console do Firebase.

  2. Clique em Adicionar projeto e selecione ou insira um Nome do projeto.

    • Se você tiver um projeto do Google associado ao seu aplicativo, selecione o projeto no menu suspenso Nome do projeto.
    • Se você não tiver um projeto do Google existente, insira um novo Nome do projeto.
  3. (Opcional) Edite o código do projeto.

    O Firebase atribui automaticamente um código exclusivo ao seu projeto do Firebase. Ele é exibido em serviços do Firebase visíveis publicamente, por exemplo:

    • URL padrão do banco de dados: your-project-id.firebaseio.com
    • subdomínio de hospedagem padrão: your-project-id.firebaseapp.com
  4. Siga as demais etapas de configuração e clique em Criar projeto ou Adicionar Firebase, se estiver usando um projeto existente do Google.

O Firebase provisiona recursos automaticamente para seu projeto da plataforma. O processo normalmente leva alguns minutos. Quando o processo for concluído, você será direcionado para a página de visão geral do seu projeto no Console do Firebase.

Android

  1. Clique em Adicionar o Firebase ao app para Android e siga as etapas de configuração. Se você estiver importando um projeto do Google, isso pode ocorrer automaticamente. Basta fazer o download do arquivo de configuração.
  2. Quando solicitado, digite o nome do pacote do seu app. É importante inserir o nome do pacote usado pelo seu aplicativo, mas essa configuração só pode ser feita quando você adiciona um app ao seu projeto do Firebase.
  3. Durante o processo, você fará o download de um arquivo google-services.json. É possível fazer o download dele novamente a qualquer momento.
  4. Depois de adicionar o código de inicialização, execute seu aplicativo para enviar ao Console do Firebase a confirmação de que você instalou o Firebase com sucesso.

iOS

  1. Clique em Adicionar o Firebase ao app para iOS e siga as etapas de configuração. Se você estiver importando um projeto do Google, isso pode ocorrer automaticamente. Basta fazer o download do arquivo de configuração.
  2. Quando solicitado, digite o código do pacote do app. É importante inserir essa informação ao adicionar um app ao projeto do Firebase.
  3. Durante o processo, você fará o download de um arquivo GoogleService-Info.plist. Você pode fazer o download desse arquivo novamente a qualquer momento.
  4. Depois de adicionar o código de inicialização, execute seu aplicativo para enviar ao Console do Firebase a confirmação de que você instalou o Firebase com sucesso.
  5. Arraste o arquivo GoogleService-Info.plist, transferido por download, do Console do Firebase para qualquer pasta no projeto do Unity.

Adicionar o SDK para Unity do Firebase ao app

  1. Faça o download do SDK para Unity do Firebase.
  2. Selecione o item de menu Recursos > Importar pacote > Pacote personalizado.
  3. Importe FirebaseDatabase.unitypackage do diretório que corresponde à versão do Unity que você usa:
    • Unity 5.x e versões anteriores usam o .NET Framework 3.x. Portanto, é necessário importar o pacote dotnet3/FirebaseDatabase.unitypackage .
    • O Unity 2017.x e versões mais recentes permitem o uso do .NET Framework 4.x. Caso seu projeto esteja configurado para usar .NET 4.x, importe o pacote dotnet4/FirebaseDatabase.unitypackage .
  4. Quando a janela Importar pacote do Unity for exibida, clique no botão Importar.

Inicializar o SDK

O SDK para Unity do Firebase no Android requer a plataforma Google Play Services, que precisa estar atualizada antes que o SDK possa ser usado. O código a seguir precisa ser adicionado no início do seu aplicativo para verificar e, como opção, atualizar o Google Play Services para a versão exigida pelo SDK para Unity do Firebase antes de chamar outros métodos no SDK.

Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
  var dependencyStatus = task.Result;
  if (dependencyStatus == Firebase.DependencyStatus.Available) {
    // Create and hold a reference to your FirebaseApp, i.e.
    //   app = Firebase.FirebaseApp.DefaultInstance;
    // where app is a Firebase.FirebaseApp property of your application class.

    // Set a flag here indicating that Firebase is ready to use by your
    // application.
  } else {
    UnityEngine.Debug.LogError(System.String.Format(
      "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
    // Firebase Unity SDK is not safe to use here.
  }
});

Criar o aplicativo

Android

  1. Selecione a opção de menu Arquivo > Criar configurações.
  2. Selecione Android na lista Plataforma.
  3. Clique em Alterar plataforma para selecionar Android como a plataforma de destino.
  4. No canto inferior direito da barra de status do Unity, espere o ícone de carregamento parar.
  5. Clique em Criar e executar.

iOS

  1. Selecione a opção de menu Arquivo > Criar configurações.
  2. Selecione iOS na lista Plataforma.
  3. Clique em Alterar plataforma para selecionar iOS como a plataforma de destino.
  4. No canto inferior direito da barra de status do Unity, espere o ícone de carregamento parar.
  5. Clique em Criar e executar.

Como estruturar dados

Este guia aborda alguns dos principais conceitos de arquitetura de dados e práticas recomendadas para estruturar dados JSON no seu Firebase Realtime Database.

Criar corretamente um banco de dados estruturado exige planejamento. O mais importante é planejar como os dados serão salvos e depois recuperados para tornar esse processo o mais fácil possível.

Como os dados são estruturados: uma árvore JSON

Todos os dados do Firebase Realtime Database são armazenados como objetos JSON. Pense no banco de dados como uma árvore JSON hospedada na nuvem. Ao contrário de um banco de dados SQL, não há tabelas nem registros. Quando você adiciona dados à árvore JSON, eles se tornam nodes na estrutura JSON existente com a chave associada. Você pode fornecer suas próprias chaves, como códigos do usuário ou nomes semânticos, ou obtê-los usando o método Push().

Caso queira criar as próprias chaves, codifique-as em UTF-8. Elas podem ter até 768 bytes e não podem conter os caracteres ., $, #, [, ] e / nem os caracteres de controle ASCII de 0 a 31 ou 127. Não é possível usar caracteres de controle ASCII nos próprios valores.

Por exemplo, pense em um aplicativo de bate-papo em que os usuários armazenam um perfil básico e uma lista de contatos. Um perfil típico está localizado em um caminho, como /users/$uid. O usuário alovelace teria uma entrada de banco de dados parecida com esta:

{
  "users": {
    "alovelace": {
      "name": "Ada Lovelace",
      "contacts": { "ghopper": true },
    },
    "ghopper": { ... },
    "eclarke": { ... }
  }
}

O banco de dados usa uma árvore JSON, mas os dados armazenados nele podem ser representados como tipos nativos que correspondam a tipos JSON disponíveis. Assim, você escreve códigos mais fáceis de atualizar.

Práticas recomendadas para a estruturação dos dados

Evitar o aninhamento

Graças ao aninhamento de dados com até 32 níveis de profundidade do Firebase Realtime Database, talvez você julgue que essa deveria ser a estrutura padrão. Mas quando você busca dados em um local do banco de dados, também recupera todos os nós filhos. Além disso, quando concede a um usuário o acesso de leitura ou gravação a um nó do banco de dados, ele também pode acessar todos os dados desse nó. Portanto, na prática, é melhor manter a estrutura de dados o mais simples possível.

Confira por que não é recomendável aninhar dados. Considere esta estrutura de vários aninhamentos:

{
  // This is a poorly nested data architecture, because iterating the children
  // of the "chats" node to get a list of conversation titles requires
  // potentially downloading hundreds of megabytes of messages
  "chats": {
    "one": {
      "title": "Historical Tech Pioneers",
      "messages": {
        "m1": { "sender": "ghopper", "message": "Relay malfunction found. Cause: moth." },
        "m2": { ... },
        // a very long list of messages
      }
    },
    "two": { ... }
  }
}

Com esse projeto aninhado, a iteração dos dados se torna um problema. Por exemplo, para listar os títulos de conversas de bate-papo, é necessário fazer o download de toda a árvore chats para o cliente, inclusive os membros e as mensagens.

Simplificar estruturas de dados

Se, em vez disso, os dados forem divididos em caminhos separados, como um processo de desnormalização, o download poderá ser feito em chamadas separadas, conforme a necessidade. Veja esta estrutura simplificada:

{
  // Chats contains only meta info about each conversation
  // stored under the chats's unique ID
  "chats": {
    "one": {
      "title": "Historical Tech Pioneers",
      "lastMessage": "ghopper: Relay malfunction found. Cause: moth.",
      "timestamp": 1459361875666
    },
    "two": { ... },
    "three": { ... }
  },

  // Conversation members are easily accessible
  // and stored by chat conversation ID
  "members": {
    // we'll talk about indices like this below
    "one": {
      "ghopper": true,
      "alovelace": true,
      "eclarke": true
    },
    "two": { ... },
    "three": { ... }
  },

  // Messages are separate from data we may want to iterate quickly
  // but still easily paginated and queried, and organized by chat
  // conversation ID
  "messages": {
    "one": {
      "m1": {
        "name": "eclarke",
        "message": "The relay seems to be malfunctioning.",
        "timestamp": 1459361875337
      },
      "m2": { ... },
      "m3": { ... }
    },
    "two": { ... },
    "three": { ... }
  }
}

Agora é possível percorrer a lista de salas fazendo o download de apenas alguns bytes por conversa, recuperando rapidamente metadados para listagem ou exibindo salas em uma IU. As mensagens podem ser carregadas separadamente e exibidas à medida que chegam, deixando a IU responsiva e rápida.

Criar dados escalonáveis

Para criar apps, recomenda-se fazer o download de um subconjunto de uma lista. Isso é muito comum se a lista tiver milhares de registros. Quando essa relação é estática e unidirecional, basta agrupar os objetos filhos subordinados ao pai.

Às vezes, essa relação é mais dinâmica e convém desnormalizar esses dados usando uma consulta para recuperar um subconjunto de dados, conforme discutido em Recuperar dados.

Entretanto, até isso pode ser insuficiente. Considere, por exemplo, uma relação bidirecional entre usuários e grupos. Os usuários podem pertencer a um grupo, e os grupos incluem uma lista de usuários. A dificuldade aparece na hora de decidir a quais grupos um usuário pertence.

É necessário encontrar um meio eficiente de listar os grupos a que um usuário pertence e buscar dados somente desses grupos. Um índice dos grupos pode ser muito útil neste caso:

// An index to track Ada's memberships
{
  "users": {
    "alovelace": {
      "name": "Ada Lovelace",
      // Index Ada's groups in her profile
      "groups": {
         // the value here doesn't matter, just that the key exists
         "techpioneers": true,
         "womentechmakers": true
      }
    },
    ...
  },
  "groups": {
    "techpioneers": {
      "name": "Historical Tech Pioneers",
      "members": {
        "alovelace": true,
        "ghopper": true,
        "eclarke": true
      }
    },
    ...
  }
}

Você perceberá que alguns dados são duplicados quando a relação é armazenada tanto no registro de Ada como no grupo. alovelace está indexado em um grupo, e techpioneers está listado no perfil de Ada. Então, para excluir Ada do grupo, é necessário que isso seja atualizado nos dois locais.

Essa é uma redundância necessária nas relações bidirecionais. Ela permite que as associações de Ada sejam carregadas de maneira rápida e eficiente, mesmo quando a lista de usuários ou grupos atinge milhões ou quando as regras de segurança do Realtime Database impedem o acesso a alguns dos registros.

Essa abordagem, ao inverter os dados listando os códigos como chaves e definindo o valor como true, torna a verificação de uma chave uma tarefa tão simples quanto ler /users/$uid/groups/$group_id e verificar se ele é null. O índice é mais rápido e muito mais eficiente do que o envio de consultas ou a varredura dos dados.

Próximas etapas

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.