Sincronizar dados

A maioria dos apps integrados à Conexão Saúde tem o próprio repositório de dados que funciona como a fonte da verdade. A Conexão Saúde oferece maneiras de manter seu app sincronizado.

Além disso, seu app precisa fazer o seguinte:

  • Inserir dados novos ou atualizados do seu repositório de dados na Conexão Saúde.
  • Extrair mudanças de dados da Conexão Saúde, que vão aparecer no repositório de dados do app.
  • Excluir dados da Conexão Saúde quando são excluídos do repositório de dados do app.

Em cada caso, o processo de sincronização precisa manter a Conexão Saúde e o repositório de dados do app alinhados.

Inserir dados na Conexão Saúde

A primeira parte do processo de sincronização é inserir os dados do repositório de dados do app no repositório da Conexão Saúde.

Preparar os dados

Normalmente, os registros no repositório de dados do app têm os detalhes abaixo:

  • Uma chave exclusiva, como UUID.
  • Uma versão ou um carimbo de data/hora.

Crie o repositório de dados para monitorar quais dados já foram enviados à Conexão Saúde. Para isso, aplique a seguinte lógica:

  • Disponibilize uma lista de mudanças e um token que possa ser usado para extrair registros com atualizações desde a emissão do último token.
  • Verifique a última vez em que houve modificação nos dados exportados.

Essas etapas são essenciais para garantir que apenas dados novos ou atualizados sejam enviados à Conexão Saúde.

Gravar dados na Conexão Saúde

Para inserir dados na Conexão Saúde, siga estas etapas:

  1. Acesse uma lista de entradas novas ou atualizadas do repositório de dados do seu app.
  2. Para cada entrada, crie um objeto Record relevante a esse tipo de dados. Por exemplo, crie um objeto WeightRecord para dados relacionados ao peso.
  3. Especifique um objeto Metadata para cada Record com os detalhes da chave exclusiva e da versão do repositório de dados do seu app. Se não houver controle de versões dos dados, use o valor Long do carimbo de data/hora atual como alternativa.

    val record = WeightRecord(
        metadata = Metadata(
            clientRecordId = "<Your record's Client ID>",
            clientRecordVersion = <Your record's version>
        ),
        weight = weight,
        time = time,
        zoneOffset = zoneOffset
    )
    
  4. Insira e atualize os dados na Conexão Saúde usando insertRecords. Dessa forma, todos os dados atuais da Conexão Saúde serão substituídos, desde que os valores de clientRecordId existam no repositório de dados desse app e a clientRecordVersion seja mais recente que o valor atual. Caso contrário, os dados serão gravados como novos.

    healthConnectClient.insertRecords(arrayListOf(record))
    

Para aprender as considerações funcionais sobre inserção de dados, confira as práticas recomendadas para Gravar dados.

Armazenar IDs da Conexão Saúde

Depois de inserir e atualizar os registros na Conexão Saúde, o repositório de dados do seu app precisa armazenar o id de cada registro. Assim, o app pode verificar se cada mudança exige a criação de um novo registro ou a atualização de um registro já existente depois de extrair os dados.

A função insertRecords retorna uma InsertRecordsResponse que contém a lista de valores de id. Use a resposta para extrair os IDs de registro e armazená-los.

val response = healthConnectClient.insertRecords(arrayListOf(record))

for (recordId in response.recordIdsList) {
    // Store recordId to your app's datastore
}

Extrair dados da Conexão Saúde

A segunda parte do processo de sincronização é extrair qualquer mudança de dados da Conexão Saúde para o repositório de dados do seu app. Essas mudanças podem incluir atualizações e exclusões.

Extrair um token de mudanças

Para conferir uma lista de mudanças extraídas da Conexão Saúde, seu app precisa acompanhar os tokens de mudanças. Use-os para retornar uma lista de mudanças de dados e um novo token de mudanças para ser usado na próxima vez.

Para acessar um token de mudanças, chame getChangesToken e forneça os tipos de dados necessários.

val changesToken = healthConnectClient.getChangesToken(
    ChangesTokenRequest(recordTypes = setOf(WeightRecord::class))
)

Verificar se há mudanças nos dados

Agora que você já tem o token de mudanças, use-o para conferir todas as mudanças. Recomendamos a criação de uma repetição para analisar todas as mudanças em que ele verifica se há mudanças de dados disponíveis. Siga estas etapas:

  1. Chame getChanges usando o token para conferir uma lista de mudanças.
  2. Verifique se cada tipo de mudança é uma UpsertionChange ou uma DeletionChange e realize as operações necessárias.
    • Para UpsertionChange, faça apenas as mudanças que não vieram do app de chamada, para não importar novamente os dados.
  3. Atribua o próximo token de mudanças como seu novo token.
  4. Repita as etapas de 1 a 3 até que não haja mais mudanças.
  5. Armazene o próximo token e reserve para uma importação futura.
suspend fun processChanges(token: String): String {
    var nextChangesToken = token
    do {
        val response = healthConnectClient.getChanges(nextChangesToken)
        response.changes.forEach { change ->
            when (change) {
                is UpsertionChange ->
                    if (change.record.metadata.dataOrigin.packageName != context.packageName) {
                        processUpsertionChange(change)
                    }
                is DeletionChange -> processDeletionChange(change)
            }
        }
        nextChangesToken = response.nextChangesToken
    } while (response.hasMore)
    // Return and store the changes token for use next time.
    return nextChangesToken
}

Para aprender as considerações funcionais sobre extração de dados, confira as práticas recomendadas para Sincronizar dados.

Processar mudanças nos dados

Mostre as mudanças no repositório de dados do seu app. Para UpsertionChange, use o id e a lastModifiedTime de metadata para inserir e atualizar o registro. Para DeletionChange, use o id fornecido para excluir o registro.

Excluir dados da Conexão Saúde

Quando um usuário excluir os próprios dados do app, verifique se também foram removidos da Conexão Saúde. Use deleteRecords para fazer isso. Isso usa um tipo de registro e uma lista de valores id e clientRecordId, o que facilita agrupar vários dados para exclusão. Um deleteRecords alternativo que usa um timeRangeFilter também está disponível.

Práticas recomendadas para sincronizar dados

Os fatores abaixo afetam o processo de sincronização.

Expiração do token

Como um token de mudanças não usado expira após 30 dias, é necessário usar uma estratégia de sincronização que evite perder informações nesse caso. Sua estratégia pode incluir as abordagens abaixo:

  • Pesquise no repositório de dados do seu app o registro consumido mais recentemente que também tem um id da Conexão Saúde.
  • Solicite registros da Conexão Saúde que começam com um carimbo de data/hora específico. Depois, insira ou atualize esses registros no repositório de dados do app.
  • Solicite um token de mudanças para reservá-lo para a próxima vez que for necessário.

Estratégias de gestão de mudanças recomendadas

Caso seu app receba tokens de mudanças inválidos ou expirados, recomendamos as estratégias de gerenciamento abaixo, dependendo de como o token será aplicado na sua lógica:

  • Ler e eliminar a duplicação de todos os dados. Essa é a estratégia ideal.
    • Armazenar o carimbo de data/hora da última vez que os dados foram lidos na Conexão Saúde.
    • Na expiração do token, leia novamente todos os dados do carimbo de data/hora mais recente ou dos últimos 30 dias. Em seguida, exclua os dados lidos anteriormente usando identificadores.
    • O ideal é implementar IDs dos clientes porque eles são necessários para atualizações de dados.
  • Ler somente os dados desde o último carimbo de data/hora de leitura. Isso resulta em algumas discrepâncias de dados relacionados ao tempo de expiração do token de mudanças, mas o período é mais curto, o que pode ser de algumas horas a alguns dias.
    • Armazenar o carimbo de data/hora da última vez que os dados foram lidos na Conexão Saúde.
    • Quando o token expirar, leia todos os dados a partir desse carimbo de data/hora.
  • Excluir e ler os dados dos últimos 30 dias. Isso é mais consistente com o que acontece na primeira integração.
    • Exclua todos os dados da Conexão Saúde lidos pelo app nos últimos 30 dias.
    • Depois da exclusão, leia todos os dados de novo.
  • Ler dados dos últimos 30 dias sem eliminar duplicações. Essa é a estratégia menos indicada e resulta na exibição de dados duplicados para os usuários.
    • Exclua todos os dados da Conexão Saúde lidos pelo app nos últimos 30 dias.
    • Permita entradas duplicadas.

Tokens de mudanças de tipos de dados

Se o app consumir mais de um tipo de dado de forma independente, use tokens de mudança separados para cada tipo. Use uma lista de vários tipos de dados com a API Changes Sync apenas se eles forem consumidos em conjunto ou se não forem usados.

Leituras em primeiro plano

Os apps só podem ler dados da Conexão Saúde enquanto estão em primeiro plano. Ao sincronizar dados da Conexão Saúde, o acesso a ela pode ser interrompido a qualquer momento. Por exemplo, o app precisa processar interrupções durante uma sincronização ao ler uma grande quantidade de dados da Conexão Saúde e continuar na próxima vez que for aberto.

Importar marcações de tempo

Como o app não pode ser notificado sobre novos dados, ele precisa verificar novos dados em dois pontos:

  • Sempre que o app ficar ativo em primeiro plano. Nesse caso, use eventos do ciclo de vida.
  • Periodicamente, enquanto o app permanecer em primeiro plano. Notifique os usuários quando novos dados estiverem disponíveis. Dessa forma, eles podem atualizar a tela para refletir as mudanças.