Blog oficial para desenvolvedores que falam português
Estratégias de carregamento do Firebase Remote Config
07/04/2017
Todd Kerpelman
Developer Advocate
Se você é fã do nosso
canal FirebaseDevelopers
, deve ter percebido que acabamos de publicar 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 blog 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:
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.
Depois, você pode chamar
fetch()
para baixar os novos valores da nuvem
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. E, 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()
. E, 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 de 0 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!
Labels
+page
1
20th Century Fox
1
A/B
1
Action
1
Action Console
1
Actions
3
Actions Console
1
Actions on Google
1
ActiveQA
1
Adaptive Battery
1
AddThis
1
ADK
1
ADL
1
Admin do Firebase
1
AdMob
6
Ads
2
AdWords
1
AdX
1
AI
4
algoritmo
1
AMP
6
AMP Linker
1
AMP Project
1
Analytics API
1
Android
58
Android 8.0 Oreo
1
Android 8.1
1
Android ADK
2
Android API
2
Android App Bundle
1
Android Dev Summit
1
Android Developers
23
Android Marshmallow
1
Android N
3
Android Nougat
2
Android P
3
Android P Beta 2
1
Android Preview
1
Android SDK
1
android studio
8
Android Studio 3.2
1
android wear
2
AndroidDev
6
AndroidX
1
Announcement
2
AoG
1
AoGDevs
1
api
15
API 25
1
API 28
1
APIs
4
Aplicativos
4
app
1
App Engine
1
Apple
1
apply
1
Apps
9
AR
1
ARCore
3
artificial intelligence
1
AsyncTask
1
AUC
1
AutoAugment
1
Avro
1
Awareness API
1
Biblioteca do Google
1
Big Data
1
BigQuery
1
BiometricPrompt
1
bitcode
1
Borg
1
Bot
1
bytecode Dalvik
1
C++
1
câmera
1
CameraDevice
1
Canal Beta
1
canary
1
câncer de próstata
1
Capital One
1
Cast
1
CFI
1
Chrome
8
Chrome 68
1
Chrome Dev Summit
1
Chrome DevTools
1
Chrome OS
2
Chromecast
1
Chromium
2
CI
1
CLI
1
Cloud
6
Cloud Computing
1
Cloud Console
1
Cloud Dataflow
1
Cloud Developers
2
Cloud DLP
1
Cloud Firestore
1
Cloud Messaging
1
Cloud ML Engine
1
Cloud Scheduler
1
Cloud Shell
1
Cloud Source Repositories
1
Cloud Spanner
2
CodeSchool
1
código aberto
2
Compute Engine
1
ConfigMap
1
Container Builder
1
CPU
2
Crash Reporting
2
Crashlytics
3
credential api
1
criptografia
1
CSS
3
CSS Grid Layout
1
CSV
1
CTA
1
Curitiba
1
Dart API
1
Data Validation
1
DBAs
1
DCGAN
1
Desenvolvedores Google
11
Desenvolvimento
3
DevBusBrasil
1
DevBytes
2
Developer Bus
1
Developer Preview
1
developer quiz
1
DevFest
3
DevFest16
1
DevFest18
1
DevFestW
1
DFP
2
Dialogflow
1
DLP
1
DLS
1
documentação
1
Dragon Ball Legends
1
E2E
1
eclipse
1
end-to-end-encryption
1
Estimator
1
Estimators API
1
estudantes
1
Eventos
15
Famílias multilíngue
1
FCM
2
Featured
1
Firebase
24
Firebase Analytics
6
Firebase App Indexing
2
Firebase Cloud Messaging
5
Firebase Crashlytics
2
Firebase Dynamic Links
3
Firebase In-App Messaging
1
Firebase Invites
2
Firebase Lab
1
Firebase Links Dinamicos
1
Firebase Notifications
3
Firebase Remote Config
1
Flutter
3
FRR
1
G+
1
game
1
game dev
3
Games
2
games services
1
GCloud
3
GCM
1
GCP
7
GDD
7
GDE
1
GDEs
1
GDG
12
GDG Curitiba
1
GDG Floripa
1
GDG OpenSampa
1
GDG Porto Alegre
1
GDG Recife
1
GDG SP
3
GDGs
1
GDL
1
Git
1
GitHub
1
GNMT
1
Google
3
Google Ad Manager
1
Google AI
1
Google Analytics
1
Google Assistant
1
Google Assistente
3
Google Brain
2
Google Cast SDK
1
google clou
1
Google Cloud
17
Google Cloud Certified
1
Google Cloud Healthcare API
1
Google Cloud Platform
3
google code-in
1
Google Developer Advocate
1
Google Developer Expert
1
Google Developers
11
Google Fotos
1
Google I/O
6
Google Play
16
Google Play Games services
1
Google Play Protect
1
Google Play Services
4
Google Slides
1
Google Speech
1
google summer of code
1
Google+
2
Google+ sign-in
1
Googlers
1
GPU
2
GSuites
1
GUI
1
Hackathon
1
Hangouts
1
Hangouts Chat
1
HDR
1
High Quality Apps
2
HTML5
6
HTTP
3
HTTPS
2
HttpURLConnection
2
I/O
1
IA
2
Illusive Images
1
ImageReader
1
In-App Messaging
1
Inglês
1
Instant Apps
1
inteligencia artificial
1
IntelliJ REPL
1
IntentService
1
Interoperabilidade
1
IO Extended
1
IO13
1
iOS
9
IU
2
Java
1
Java 8
1
javascript
2
JPEG
1
JSON
2
Kaggle
1
kernel
1
Keyboard Map API
1
Knowledge Connectors
1
Kotlin
6
Kotlin da Udacity
1
Kubernetes
5
LangID
1
Launchpad
1
launchpad accelerator
2
Learning Augmentation
1
LEGO
1
Listas
1
ListFragment
1
LLVM
1
LTO
1
Machine Learning
2
Meetup
2
mensagens
1
Mentoria
1
Messaging
2
microsserviços
1
ML
2
ML Kit
1
Mobile
3
Mobile Ads SDK
1
Monetização
3
Monetize
3
MySQL
1
Native
1
Navigation Architecture Component
1
NES
1
Neto Marin
2
Next Level Apps
2
Next Level Tips
2
NNLM
1
Node.js
2
Notificações
1
novembro azul
1
Number Genie
1
Nuvem Profissional
1
OAuth
2
OAuth2
1
Open Images Extended
1
open source
3
Options Menu
1
Options Menu virtual
1
Orkut
2
Payment Request
1
pesquisa
1
PHA
1
Phone Gateway
1
PII
1
pixel
1
Play Academy
1
Play Console
1
Play Services
1
Playtime 2018
1
plug-in AMP
1
Porto Alegre
1
Preact
1
PRIV
1
program
1
progressive web apps
2
Push Notification
2
Python
1
QA
1
RA
2
Raspberry Pi
1
RBDMS
1
React
1
recording apis
1
remarketing
1
Remote Config
2
research
4
ResultReceiver
1
reward
1
RNN
2
Robolectric 4.0
1
RV
1
Sceneform
1
SDK
4
SDK Manager
3
Security
2
Server
1
service worker
1
sign-in
1
Sliding Tabs
1
Smartronix
1
social
6
Spark
1
SRE
1
Stack
1
Stack Overflow
1
Startups
2
Storage
2
story
1
Support Library
1
SurfaceView
1
Svelte
1
switch
1
Tag Manager
1
Tag Manager 360
1
tensorflow
5
TensorFlow Hub
2
TensorFlow Lite
1
TensorFlow Transform
1
Test Lab
2
Testes
1
TF Hub
2
tf.keras
1
TFDV
1
TFX
1
TI essencial
1
toolkit
1
tradução
1
TTS
1
Udacity
1
Universal Apps
1
Universal Sentence Encoder
1
user experience
1
ux
1
VectorDrawable
1
Velostrata
1
Volley
1
vr
2
vulnerabilidades
1
vulnerabilidades do Google
1
vulnerability
1
web
2
web dev
2
WebKit
1
webservice
3
when
1
WordPress
1
WorkerDOM
1
YouTube
4
YouTube API
1
YUV
1
Zomato
1
Archive
2022
nov.
out.
jul.
jun.
mai.
abr.
mar.
fev.
jan.
2021
dez.
nov.
out.
set.
ago.
jul.
jun.
mai.
abr.
mar.
fev.
jan.
2020
dez.
nov.
out.
set.
ago.
jul.
jun.
mai.
abr.
mar.
fev.
jan.
2019
dez.
nov.
out.
set.
ago.
jul.
jun.
mai.
abr.
2018
dez.
nov.
out.
set.
ago.
jul.
jun.
mai.
abr.
mar.
fev.
2017
ago.
jul.
jun.
mai.
abr.
mar.
jan.
2016
dez.
nov.
out.
set.
ago.
jul.
mai.
mar.
2014
jul.
jun.
abr.
mar.
fev.
2013
dez.
nov.
out.
set.
ago.
jul.
jun.
mai.
mar.
fev.
jan.
2012
nov.
jul.
jun.
mai.
abr.
mar.
2011
nov.
set.
ago.
jul.
jun.
Feed
Follow @googledevbr