Desenvolvimento

17 abr, 2017

Estratégias de carregamento do Firebase Remote Config

Publicidade

Artigo de Todd Kerpelman, publicado originalmente pelo Google Developers Brazil.

***

Se você é fã do nosso canal FirebaseDevelopers, deve ter percebido que publicamos recentemente um vídeo apenas sobre como carregar valores do Remote Config no seu aplicativo da melhor forma. Mas, sabemos que alguns preferem ler a assistir a um vídeo, então, pensamos em oferecer esse conteúdo em formato de texto também!

Por isso, se você já trabalhou com o Remote Config, provavelmente percebeu que há três principais etapas para se implementar o Remote Config no seu aplicativo:

  1. Você fornece ao Remote Config um monte de valores padrão. Isso acontece localmente no dispositivo, no código ou inserindo os valores a partir de um arquivo xml ou plist local.
  2. Depois, você pode chamar fetch() para baixar os novos valores da nuvem.
  3. Por fim, você chama activateFetched() para substituir os valores padrão originalmente definidos por esses valores baixados.

Nesse momento, quando você consulta um determinado valor no Remote Config, recebe o valor atualizado da nuvem ou qualquer padrão que você tenha fornecido localmente. E isso é muito bom, porque você pode conectar o seu aplicativo para coletar todos esses valores pelo Remote Config. Você ainda mantém as chamadas de rede convenientemente pequenas, pois só está baixando os valores que são diferentes dos seus valores padrão, mas agora com a flexibilidade de poder alterar qualquer aspecto do aplicativo depois pela nuvem.

Bem simples, não é? E, em grande parte, é simples mesmo. O problema é que a etapa 2 exige fazer uma chamada de rede e, no mundo real, onde pessoas usam aplicativos em túneis, elevadores, desertos e locais com baixo sinal de rede, nunca se sabe quanto tempo vai levar para essa chamada de rede ser concluída. Não é possível garantir que esse processo seja finalizado antes de o usuário começar a interagir com o aplicativo.

Considerando isso, então, vejamos três estratégias que você pode implementar:

Estratégia 1: ativar e atualizar

Essa estratégia é a mais simples e direta, portanto, ela é a mais comum nos nossos aplicativos e tutoriais de exemplo. A ideia é que, depois de baixar esses novos valores da nuvem, você chame activateFetched() no gerenciador de conclusão para aplicá-los imediatamente e, depois, libere o aplicativo para seguir para a atualização.

Essa estratégia é bem legal, porque permite que o usuário entre direto no aplicativo. No entanto, é um pouco esquisito que o seu aplicativo possa mudar coisas como texto de botões, a diagramação da IU ou outros valores críticos enquanto o usuário está usando, o que pode gerar uma experiência de uso ruim. É por isso que muitos desenvolvedores optam por uma solução como a…

Estratégia 2: adicionar uma tela de carregamento

Uma estratégia bem comum é exibir uma tela de carregamento quando o usuário inicializa o aplicativo. Assim como antes, você chama activateFetched no gerenciador de conclusão para aplicar os valores imediatamente mas, em vez de liberar o aplicativo para atualizar a interface, você instrui o aplicativo a descartar a tela de carregamento e iniciar a transição para o conteúdo principal. Isso funciona bem porque, no momento em que os usuários passam da tela de carregamento e entram no aplicativo, é praticamente certo que você tenha os valores atuais baixados da nuvem e tudo esteja no seu devido lugar.

Obviamente, a grande desvantagem nesse caso é que agora você tem uma tela de carregamento. É preciso tempo e esforço para criá-la, além de ser uma barreira para os usuários que entram no aplicativo. Mas, se o aplicativo já tem uma tela de carregamento porque você tem que realizar outras tarefas e/ou chamadas de rede na inicialização, essa pode ser uma boa estratégia. É só buscar os valores da configuração remota junto das outras tarefas de inicialização que são feitas.

No entanto, se o aplicativo não tiver uma tela de carregamento, recomendo tentar uma estratégia alternativa. Algo como a…

Estratégia 3: carregar valores para o próximo uso

Essa parece um pouco incomum, mas deixe eu explicar: quando o usuário inicializa o aplicativo, você chama activateFetched() imediatamente. Isso aplicará todos os valores antigos buscados previamente na nuvem. Depois, o usuário poderá começar a interagir imediatamente com o aplicativo.

Enquanto isso, você inicia uma chamada de fetch() assíncrona para buscar novos valores da nuvem. E no gerenciador de conclusão dessa chamada, você não faz nada. Olha que beleza: você não precisa nem adicionar um gerenciador de conclusão. Esses valores buscados na nuvem continuarão armazenados localmente no dispositivo até o usuário chamar activateFetched na próxima vez em que inicializar o aplicativo.

Essa estratégia é bem interessante, porque os usuários podem começar a usar o aplicativo imediatamente e o aplicativo não fica com aquele comportamento esquisito de mudar a interface de repente no meio do uso. A desvantagem óbvia é que é preciso que os usuários iniciem duas sessões para ver os valores atualizados da configuração remota. Você precisa decidir se esse é ou não o melhor comportamento para o seu aplicativo.

Se você usa o Remote Config para, digamos, ajustar alguns valores no seu jogo de defesa de torre, essa abordagem deve funcionar bem. Mas, se você o usa para enviar a “mensagem do dia” ou conteúdo específico de determinada data (como um design sazonal do seu aplicativo), ela pode não funcionar tão bem.

Estratégia 3.5: um híbrido das estratégias 2 e 3. Ou 1 e 3

Uma vantagem do Remote Config é que ele pode informar quando a última chamada de fetch() bem-sucedida aconteceu. E por isso, você pode criar algumas estratégias híbridas nas quais primeiro você verifica há quanto tempo a busca mais recente dos dados do Remote Config ocorreu. Se for bem recente (digamos, nas últimas 48 horas), você pode seguir em frente e aplicar a estratégia de aplicar o lote de valores mais recente e realizar outra busca para o próximo uso. Se não, você pode retornar a uma das duas estratégias anteriores.

Vamos falar sobre armazenamento em cache

Já que estamos falando de estratégias de carregamento, vamos entrar em um assunto relacionado: armazenamento em cache. Às vezes, os desenvolvedores acham (erroneamente) que os valores da configuração remota são armazenados em cache por 12 horas, em vez de serem coletados imediatamente sempre que se chama fetch(). Embora você possa reduzir esse tempo de cache um pouco, se começar a fazer chamadas de rede com muita frequência, pode limitar o aplicativo, seja pelo cliente ou pelo serviço Remote Config.

Então, por que temos esse negócio de armazenamento em cache e comportamento de limitação? Bem, parte disso é uma forma de garantir que possamos manter o serviço gratuito, mesmo que o aplicativo escalone para milhões e mais milhões de usuários. Ao adicionar um pouco de armazenamento em cache com comportamento aceitável, podemos garantir que nosso serviço possa gerenciar seu aplicativo gratuitamente, independentemente da popularidade dele.

Essa também é uma forma bem legal de proteger o serviço de códigos inapropriados. Existem alguns desenvolvedores (não você, é claro) que podem chamar fetch() com muita frequência sem querer. E não queremos que todo o serviço seja prejudicado porque um desenvolvedor está fazendo ataques DDoS nele sem querer. Fazer com que a biblioteca do cliente forneça valores armazenados em cache e/ou limitar chamadas de rede em excesso ajuda a manter o serviço seguro.

Mas, além disso tudo, isso é bom para os usuários. Uma boa estratégia de armazenamento em cache impede o aplicativo de consumir toda a bateria e/ou o plano de dados do usuário ao fazer muitas chamadas de rede desnecessárias, o que é sempre um ponto positivo.

Obviamente, durante o desenvolvimento e os testes da sua implementação do Remote Config, isso pode ser inconveniente, e é por isso que você pode neutralizar o comportamento de limitação local acionando o modo do desenvolvedor. Mas, na prática, mesmo que os usuários usem o aplicativo todos os dias, esse tipo de comportamento de armazenamento em cache normalmente funciona muito bem, obrigado.

Mas e se você quiser inserir valores com mais frequência? E se você estiver tentando enviar um recurso como uma “mensagem da hora” pelo Remote Config? Bem, francamente, esse pode ser um sinal de que o Remote Config pode não ser a solução ideal para você, por isso, considere o Realtime Database para ter algo com um pouco mais de velocidade.

Por outro lado, você pode querer aplicar uma atualização urgente ao Remote Config ocasionalmente. Talvez, você tenha errado na configuração dos preços dos produtos vendidos no aplicativo com o último lote de mudanças e quer que todo mundo receba os novos valores imediatamente. Como contornar o cache e forçar os clientes a realizar uma busca?

Uma solução é usar o Firebase Cloud Messaging. Com o FCM, você pode enviar uma notificação somente de dados a todos os dispositivos, informando-os de que há uma atualização urgente pendente. Os aplicativos podem responder a essa notificação armazenando algum tipo de sinalizador localmente. Na próxima vez em que os usuários inicializarem o aplicativo, ele poderá procurar por esse sinalizador. Se ele for definido como “true”, seu aplicativo poderá realizar uma busca com um tempo de cache d0 para que ela seja imediata. Basta não deixar de desativar esse sinalizador quando tudo estiver resolvido para o aplicativo poder retomar seu comportamento de cache comum.

Pode ser tentador fazer com que os clientes respondam a essa notificação ativando e buscando novos valores do serviço Remote Config imediatamente, mas se todas as instâncias do seu aplicativo fizerem isso simultaneamente, há uma chance considerável de você atingir o limite do servidor, então, essa é uma abordagem que eu não recomendo. Fique apenas com a estratégia acima: ela distribuirá as chamadas de rede ao longo do espaço de tempo que leva para os usuários abrirem o aplicativo.

E é isso aí, pessoal! Algumas dicas e truques para carregar os valores do Remote Config. Tem alguma dica para dar? Fique à vontade para compartilhá-la nos comentários do nosso vídeo no YouTube ou mandá-la diretamente para o grupo Firebase Talk e mostrar como você está fazendo a sua implementação do Remote Config.

Beleza, então. Ficamos por aqui. Até a próxima!

***

Artigo do Google Developers Brazil e foi escrito por Todd Kerpelman. VOcê pode ver o original em: https://desenvolvedores.googleblog.com/2017/04/estrategias-de-carregamento-do-firebase.html