Comunidade

Como as Atualizações OTA Afetam os Usuários (e por Que Isso Importa)

O artigo discute os desafios enfrentados pelos usuários durante atualizações por sobre-the-air (OTA) em aplicativos React Native, destacando problemas como prompts de atualização no meio da sessão, divergência entre o esquema do novo pacote e o estado armazenado, e atraso na adoção que gera carga de suporte. Sugere soluções como versionar o esquema de cache e expor o ID do bundle para diagnósticos rápidos.

Compartilhar
What OTA Updates Feel Like for Your Users (and Why It Matters) - DEV Community
  • Ao padrão do Expo, as atualizações são aplicadas silenciosamente no início frio. Isso é uma boa experiência de usuário apenas se o estado da aplicação não mudar entre os pacotes.
  • Três lugares onde OTA prejudica: solicitações de atualização durante a sessão, diferenças esquemáticas entre o pacote e o estado em cache e adopção adiada criando uma carga para suporte.
  • Cure as diferenças esquemáticas marcando escritas de AsyncStorage com um _schemaVersion e migrando ou removendo no início da aplicação.
  • Exponha o ID do pacote atual nas Configurações → Sobre para que suporte possa diagnosticar "que pacote você está usando?" em uma pergunta só.
  • A atualização técnica deve ser invisível. A experiencial nunca deve ser.

Toda tutorial de React Native OTA foca na experiência do desenvolvedor: eas update, pronto.

O que quase ninguém escreve sobre é o que acontece no telefone do usuário quando sua OTA chega, e como essa experiência molda se eles permanecem na aplicação ou saem dela.

Vamos passar por isso.

O que acontece quando uma OTA chega

Comportamento padrão do Expo com checkAutomatically: "ON_LOAD":

  1. O usuário abre a aplicação. A shell nativa é iniciada, splash screen aparece.
  2. Ao mesmo tempo, o cliente de atualização verifica seu servidor por um novo pacote. Se encontrado e baixado dentro do fallbackToCacheTimeout (padrão 0ms — i.e., nunca aguarde), é aplicado imediatamente.
  3. Caso o tempo limite seja atingido primeiro, o pacote em cache (anterior) carrega. O novo pacote baixa no plano de fundo e é aplicado na próxima abertura.

O usuário vê nada. Isso é o objetivo do design.

Mas "nada" é apenas uma boa experiência se o estado da aplicação não mudar entre os dois pacotes.

As três experiências de usuário onde OTA prejudica

1. Solicitação de atualização durante a sessão

Você configura checkAutomatically: "ON_ERROR_RECOVERY", pensando que só irá atualizar após um crash. O que você realmente obtém: um usuário em uma tarefa, o aplicativo cai e seu cliente de OTA busca um novo pacote — agora eles estão olhando para um aplicativo re-lançado com contexto perdido.

Melhor padrão: ON_LOAD (apenas início frio) mais uma bandeira explícita no aplicativo "Atualização disponível - reinicie para aplicar" para atualizações em sessões quentes.

2. Diferenças esquemáticas entre o pacote e o estado em cache

Seu novo pacote espera user.profile.avatarUrl. Usuários atualizando de um pacote antigo têm user.avatar em cache. Crash na primeira renderização.

Solução: versione seu esquema de cache. As escritas de AsyncStorage devem incluir uma tag _schemaVersion, e novos pacotes migram ou removem dados antigos no início da aplicação.

3. Adopção adiada e carga para suporte

Um usuário envia um email "esta funcionalidade está quebrada." Você verifica o pacote mais recente — está fixado. Mas eles estão em um pacote de três semanas atrás, porque nunca reabriram a aplicação por tempo suficiente para completar a busca no plano de fundo.

Solução: exponha o ID do pacote atual nas Configurações → Sobre. Suporte pode perguntar "o que diz?" e saber imediatamente se precisam forçar uma atualização.

The "update pending" pattern

import * as Updates from 'expo-updates';
import { useEffect, useState } from 'react';

export function useUpdatePending() {
  const [pending, setPending] = useState(false);

  useEffect(() => {
    const sub = Updates.addListener((event) => {
      if (event.type === Updates.UpdateEventType.UPDATE_AVAILABLE) {
        setPending(true);
      }
    });
    return () => sub.remove();
  }, []);

  return pending;
}
Enter fullscreen mode Exit fullscreen mode

Então, no shell do seu aplicativo:

Mostre o banner de forma não intrusiva — no topo da tela, removível. Deixe que o usuário reinicie quando estiver pronto.

A confiança supera a velocidade.

Comunicando reverterações

Caso reverta um pacote, usuários que tiveram a versão ruim por dez minutos podem ter tomado alguma ação nesse intervalo — iniciaram um formulário, tentaram uma transação. Eles retornam e o UI mudou sob eles.

Para qualquer reverteração que tocou no estado visível do usuário, envie uma pequena notificação dentro do aplicativo:

Nós revertemos uma atualização de uma hora atrás. Se você viu erros, eles devem estar resolvidos agora.

Honestidade radical. A maioria dos usuários aprecia ser informado em vez de ficar confuso.

Quando quebrar a regra da invisibilidade

Caso haja mudanças verdadeiramente significativas — nova navegação, uma tela inicial redesenhada — um OTA que silenciosamente troca coisas é pior do que uma atualização de loja com notas de liberação.

Considere criar uma barreira para mudanças UX significativas por trás de um modal "O que há de novo" dentro do aplicativo, mesmo se o código foi enviado via OTA semanas antes.

O ponto todo do OTA é que a atualização técnica é invisível. A atualização experiencial nunca deve ser.


Caso esteja iniciando um projeto React Native e deseje ter a linha de montagem de atualizações configurada desde o primeiro dia, RapidNative gera aplicativos Expo com EAS Update já configurados.

O que é sua história de pesadelo OTA? A minha foi um deslizamento do esquema, uma forma de objeto em cache que fez todos os usuários retornantes crasharem na primeira renderização.

Fonte original

Conteúdo traduzido e adaptado pela redação do Notícias Mobile. Confira também a matéria na fonte original.

Leia a matéria completa