Um feed de artigos pode crescer enquanto alguém navega por ele. A primeira página mostra os itens mais recentes. A pessoa abre um artigo, retorna e pede a página seguinte. Se a navegação usa deslocamento numérico, cada item anterior precisa ser contado de novo e uma inserção no topo pode deslocar a fronteira entre páginas. Um cursor guarda a posição a partir da qual a consulta deve continuar.

Use uma ordenação determinística

A consulta precisa ordenar os documentos por um campo que represente a sequência desejada, como a data de publicação. Se vários documentos compartilham o mesmo instante, apenas a data pode não identificar uma posição única. Use também um identificador estável como desempate, ou passe o snapshot do último documento como cursor. A ordenação e os valores do cursor precisam seguir a mesma sequência em todas as páginas.

Com limit, a primeira consulta busca uma quantidade pequena de documentos. Guarde o último documento retornado e use startAfter para pedir os seguintes. O cursor representa o ponto de continuação, não a página inteira. Para voltar à página anterior, o cliente precisa guardar os cursores já vistos ou executar uma consulta reversa desenhada para esse caso.

Decida o que acontece com novos itens

Se alguém publica um artigo enquanto o visitante já está na página dois, há duas políticas possíveis. O feed pode manter uma navegação estável e mostrar o item novo só depois de atualizar do início; ou pode refletir as mudanças imediatamente e aceitar que a posição relativa varie. O cursor evita repetir o documento usado como fronteira, mas não cria um snapshot imutável de toda a coleção.

Para um blog, manter o cursor atual e oferecer um aviso de novos artigos costuma ser mais previsível do que inserir itens antes do ponto de leitura. Em um painel operacional, a atualização imediata pode ser mais importante. Escolha com base no comportamento esperado e teste com uma inserção entre a primeira e a segunda chamada.

Valide cursores recebidos do cliente

Se o cursor fica na URL, serialize apenas os campos necessários e valide formato, tipo e tamanho antes de construir a consulta. Um cursor pode ser assinado pelo servidor para impedir que o cliente altere limites que não deveria controlar. Em páginas públicas, ele não deve conter dados privados. Se a consulta depende de tenant ou usuário, derive essa identidade da sessão autorizada, não de um parâmetro fornecido pelo visitante.

Lembre que ordenação por data, filtros por status e cursor precisam funcionar juntos. Quando rascunhos entram no mesmo feed que posts publicados, um cursor criado em uma consulta pode não apontar para o resultado correspondente em outra. Mantenha filtros, ordem e escopo idênticos entre as páginas.

Trate o fim e as mudanças do conjunto

Quando uma página retorna menos documentos que o limite, pode não existir próxima página. Também é possível buscar um documento extra para calcular hasMore e removê-lo da resposta visível. Não use apenas o tamanho do cursor anterior como prova: exclusões ou alterações de status podem reduzir a coleção entre consultas.

Teste empates de data, coleção vazia, última página, exclusão do item que servia de cursor e publicação concorrente. Confirme que nenhum documento se repete e que a interface não mostra um botão de próxima página sem resultados. Esses casos revelam problemas que uma lista imóvel de fixtures não cobre.

Firestore: paginar consultas com cursores · Firestore: preços e leituras