Ir para o console

Ativar dados off-line

O Cloud Firestore é compatível com a persistência de dados off-line. Este recurso armazena em cache uma cópia dos dados do Cloud Firestore que seu app usa ativamente. Assim, o app pode acessar os dados quando o dispositivo estiver desconectado. É possível gravar, ler, detectar e consultar os dados armazenados em cache. Quando o dispositivo for conectado novamente, o Cloud Firestore sincroniza todas as alterações locais feitas pelo app nos dados armazenados remotamente no Cloud Firestore.

Para usar a persistência off-line, não é preciso alterar o código que você usa para acessar dados do Cloud Firestore. Com a persistência off-line ativada, a biblioteca de cliente do Cloud Firestore gerencia automaticamente o acesso a dados on-line e off-line e sincroniza os dados locais quando o dispositivo for conectado novamente.

Configurar a persistência off-line

Quando você inicializa o Cloud Firestore, é possível ativar ou desativar a persistência off-line das seguintes maneiras:

  • Para Android e iOS, a persistência off-line está ativada por padrão. Para desativar esse recurso, defina a opção PersistenceEnabled como false.
  • Para a Web, a persistência off-line está desativada por padrão. Para ativá-la, chame o método enablePersistence. O cache do Cloud Firestore não é apagado automaticamente entre as sessões. Consequentemente, se o app da Web lidar com informações confidenciais, pergunte ao usuário se ele está em um dispositivo confiável antes de ativar a persistência.
Web
firebase.initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  projectId: '### CLOUD FIRESTORE PROJECT ID ###',
}
);

firebase.firestore().enablePersistence()
  .catch(function(err) {
      if (err.code == 'failed-precondition') {
          // Multiple tabs open, persistence can only be enabled
          // in one tab at a a time.
          // ...
      } else if (err.code == 'unimplemented') {
          // The current browser does not support all of the
          // features required to enable persistence
          // ...
      }
  });
// Subsequent queries will use persistence, if it was enabled successfully
  
Swift
let settings = FirestoreSettings()
settings.isPersistenceEnabled = true

// Any additional options
// ...

// Enable offline data persistence
let db = Firestore.firestore()
db.settings = settings
Objective-C
FIRFirestoreSettings *settings = [[FIRFirestoreSettings alloc] init];
settings.persistenceEnabled = YES;

// Any additional options
// ...

// Enable offline data persistence
FIRFirestore *db = [FIRFirestore firestore];
db.settings = settings;
  
Java
Android
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
        .setPersistenceEnabled(true)
        .build();
db.setFirestoreSettings(settings);
Kotlin
Android
val settings = FirebaseFirestoreSettings.Builder()
        .setPersistenceEnabled(true)
        .build()
db.firestoreSettings = settings

Detectar dados off-line

Se você tiver ativado a persistência off-line enquanto o dispositivo estiver desativado, seus listeners receberão eventos de detecção quando os dados armazenados em cache localmente forem alterados. É possível detectar documentos, coleções e consultas.

Para verificar se você está recebendo dados do servidor ou do cache, use a propriedade fromCache no SnapshotMetadata no evento de instantâneo. Se fromCache for true, os dados vieram do cache e podem estar desatualizados ou incompletos. Se fromCache for false, os dados estão completos e com as atualizações mais recentes do servidor.

Por padrão, nenhum evento é gerado quando apenas o SnapshotMetadata é alterado. Se você usa valores fromCache, especifique a opção de detecção includeMetadataChanges quando anexar seu gerenciador de detecção.

Web
db.collection("cities").where("state", "==", "CA")
  .onSnapshot({ includeMetadataChanges: true }, function(snapshot) {
      snapshot.docChanges().forEach(function(change) {
          if (change.type === "added") {
              console.log("New city: ", change.doc.data());
          }

          var source = snapshot.metadata.fromCache ? "local cache" : "server";
          console.log("Data came from " + source);
      });
  });
 
Swift
// Listen to metadata updates to receive a server snapshot even if
// the data is the same as the cached data.
db.collection("cities").whereField("state", isEqualTo: "CA")
    .addSnapshotListener(includeMetadataChanges: true) { querySnapshot, error in
        guard let snapshot = querySnapshot else {
            print("Error retreiving snapshot: \(error!)")
            return
        }

        for diff in snapshot.documentChanges {
            if diff.type == .added {
                print("New city: \(diff.document.data())")
            }
        }

        let source = snapshot.metadata.isFromCache ? "local cache" : "server"
        print("Metadata: Data fetched from \(source)")
}
Objective-C
// Listen to metadata updates to receive a server snapshot even if
// the data is the same as the cached data.
[[[db collectionWithPath:@"cities"] queryWhereField:@"state" isEqualTo:@"CA"]
    addSnapshotListenerWithIncludeMetadataChanges:YES
    listener:^(FIRQuerySnapshot *snapshot, NSError *error) {
      if (snapshot == nil) {
        NSLog(@"Error retreiving snapshot: %@", error);
        return;
      }
      for (FIRDocumentChange *diff in snapshot.documentChanges) {
        if (diff.type == FIRDocumentChangeTypeAdded) {
          NSLog(@"New city: %@", diff.document.data);
        }
      }

      NSString *source = snapshot.metadata.isFromCache ? @"local cache" : @"server";
      NSLog(@"Metadata: Data fetched from %@", source);
    }];
  
Java
Android
db.collection("cities").whereEqualTo("state", "CA")
        .addSnapshotListener(MetadataChanges.INCLUDE, new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(@Nullable QuerySnapshot querySnapshot,
                                @Nullable FirebaseFirestoreException e) {
                if (e != null) {
                    Log.w(TAG, "Listen error", e);
                    return;
                }

                for (DocumentChange change : querySnapshot.getDocumentChanges()) {
                    if (change.getType() == Type.ADDED) {
                        Log.d(TAG, "New city:" + change.getDocument().getData());
                    }

                    String source = querySnapshot.getMetadata().isFromCache() ?
                            "local cache" : "server";
                    Log.d(TAG, "Data fetched from " + source);
                }

            }
        });
Kotlin
Android
db.collection("cities").whereEqualTo("state", "CA")
        .addSnapshotListener(MetadataChanges.INCLUDE, EventListener<QuerySnapshot> { querySnapshot, e ->
            if (e != null) {
                Log.w(TAG, "Listen error", e)
                return@EventListener
            }

            for (change in querySnapshot!!.documentChanges) {
                if (change.type == DocumentChange.Type.ADDED) {
                    Log.d(TAG, "New city: ${change.document.data}")
                }

                val source = if (querySnapshot.metadata.isFromCache)
                    "local cache"
                else
                    "server"
                Log.d(TAG, "Data fetched from $source")
            }
        })

Receber dados off-line

Se você recebe um documento enquanto o dispositivo está off-line, o Cloud Firestore retorna os dados do cache. Se o cache não contém dados para o documento ou se este não existe, a chamada de recebimento retorna um erro.

Consultar dados off-line

As consultas funcionam com a persistência off-line. É possível recuperar os resultados das consultas por meio de recebimentos diretos e por detecção, conforme descrito nas seções anteriores. Também é possível criar novas consultas em dados com persistência definida localmente enquanto o dispositivo está off-line. Porém, a princípio, elas são executadas apenas nos documentos armazenados em cache.

Desativar e ativar o acesso à rede

Use o método abaixo para desativar o acesso à rede no cliente do Cloud Firestore. Enquanto o acesso à rede está desativado, todos os listeners de instantâneo e solicitações de documento recuperam os resultados do cache. As operações de gravação são enfileiradas até que o acesso à rede seja reativado.

Web
firebase.firestore().disableNetwork()
    .then(function() {
        // Do offline actions
        // ...
    });
  
Swift
Firestore.firestore().disableNetwork { (error) in
    // Do offline things
    // ...
}
Objective-C
[[FIRFirestore firestore] disableNetworkWithCompletion:^(NSError *_Nullable error) {
  // Do offline actions
  // ...
}];
  
Java
Android
db.disableNetwork()
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                // Do offline things
                // ...
            }
        });
Kotlin
Android
db.disableNetwork().addOnCompleteListener {
    // Do offline things
    // ...
}

Use o método a seguir para reativar o acesso à rede:

Web
firebase.firestore().enableNetwork()
    .then(function() {
        // Do online actions
        // ...
    });
  
Swift
Firestore.firestore().enableNetwork { (error) in
    // Do online things
    // ...
}
Objective-C
[[FIRFirestore firestore] enableNetworkWithCompletion:^(NSError *_Nullable error) {
  // Do online actions
  // ...
}];
  
Java
Android
db.enableNetwork()
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                // Do online things
                // ...
            }
        });
Kotlin
Android
db.enableNetwork().addOnCompleteListener {
    // Do online things
    // ...
}