Buka konsol

Mengakses data secara offline

Cloud Firestore mendukung persistensi data offline. Operasi ini meng-cache salinan data Cloud Firestore yang digunakan secara aktif oleh aplikasi Anda, sehingga aplikasi dapat mengakses data saat perangkat sedang offline. Anda bisa menulis, membaca, mendeteksi, dan membuat kueri data yang disimpan di cache. Saat perangkat kembali online, Cloud Firestore akan menyinkronkan semua perubahan lokal yang dilakukan oleh aplikasi Anda ke backend Cloud Firestore.

Untuk menggunakan persistensi data offline, Anda tidak perlu membuat perubahan pada kode yang Anda gunakan untuk mengakses data Cloud Firestore. Dengan diaktifkannya persistensi data offline, library klien Cloud Firestore akan mengelola akses data online dan offline secara otomatis, serta menyinkronkan data lokal saat perangkat kembali online.

Mengonfigurasikan persistensi data offline

Saat Anda menginisialisasi Cloud Firestore, Anda dapat mengaktifkan atau menonaktifkan persistensi data offline:

  • Untuk Android dan iOS, persistensi data offline diaktifkan secara default. Untuk menonaktifkan persistensi data, setel opsi PersistenceEnabled menjadi false.
  • Untuk web, persistensi data offline dinonaktifkan secara default. Untuk mengaktifkan persistensi, panggil metode enablePersistence. Cache Cloud Firestore tidak dihapus secara otomatis di antara sesi. Oleh karena itu, jika aplikasi web Anda menangani informasi sensitif, pastikan pengguna menggunakan perangkat tepercaya sebelum mengaktifkan persistensi.
Web
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
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
        .setPersistenceEnabled(true)
        .build();
db.setFirestoreSettings(settings);
Kotlin
val settings = FirebaseFirestoreSettings.Builder()
        .setPersistenceEnabled(true)
        .build()
db.firestoreSettings = settings

Mengonfigurasikan ukuran cache

Ketika persistensi diaktifkan, Cloud Firestore menyimpan setiap dokumen yang diterima dari backend untuk akses offline dalam cache. Cloud Firestore menetapkan ambang batas default untuk ukuran cache. Setelah melebihi batas default, Cloud Firestore secara berkala akan berupaya untuk membersihkan dokumen lama yang tidak digunakan. Anda dapat mengonfigurasi ambang batas ukuran cache yang berbeda atau menonaktifkan proses pembersihan sepenuhnya:

Web
// The default cache size threshold is 40 MB. Configure "cacheSizeBytes"
// for a different threshold (minimum 1 MB) or set to "CACHE_SIZE_UNLIMITED"
// to disable clean-up.
firebase.firestore().settings({
  cacheSizeBytes: firebase.firestore.CACHE_SIZE_UNLIMITED
});

firebase.firestore().enablePersistence()
  
Swift
// The default cache size threshold is 100 MB. Configure "cacheSizeBytes"
// for a different threshold (minimum 1 MB) or set to "FirestoreCacheSizeUnlimited"
// to disable clean-up.
let settings = Firestore.firestore().settings
settings.cacheSizeBytes = FirestoreCacheSizeUnlimited
Firestore.firestore().settings = settings
Objective-C
// The default cache size threshold is 100 MB. Configure "cacheSizeBytes"
// for a different threshold (minimum 1 MB) or set to "kFIRFirestoreCacheSizeUnlimited"
// to disable clean-up.
FIRFirestoreSettings *settings = [FIRFirestore firestore].settings;
settings.cacheSizeBytes = kFIRFirestoreCacheSizeUnlimited;
[FIRFirestore firestore].settings = settings;
  
Java

// The default cache size threshold is 100 MB. Configure "setCacheSizeBytes"
// for a different threshold (minimum 1 MB) or set to "CACHE_SIZE_UNLIMITED"
// to disable clean-up.
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
        .setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED)
        .build();
db.setFirestoreSettings(settings);
Kotlin

// The default cache size threshold is 100 MB. Configure "setCacheSizeBytes"
// for a different threshold (minimum 1 MB) or set to "CACHE_SIZE_UNLIMITED"
// to disable clean-up.
val settings = FirebaseFirestoreSettings.Builder()
        .setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED)
        .build()
db.firestoreSettings = settings

Mendeteksi data offline

Saat perangkat sedang offline, jika Anda telah mengaktifkan persistensi data offline, listener akan menerima peristiwa deteksi saat terjadi perubahan pada data yang di-cache secara lokal. Anda dapat mendeteksi dokumen, koleksi, dan kueri.

Untuk memeriksa apakah Anda menerima data dari server atau cache, gunakan properti fromCache pada SnapshotMetadata di peristiwa snapshot Anda. Jika fromCache adalah true, artinya data berasal dari cache dan mungkin sudah usang atau tidak lengkap. Jika fromCache adalah false, artinya data sudah lengkap dan terkini dengan update yang terbaru di server.

Secara default, tidak ada peristiwa yang dipicu jika hanya SnapshotMetadata yang berubah. Jika Anda mengandalkan nilai fromCache, tentukan opsi pendeteksi includeMetadataChanges saat memasang pengendali deteksi Anda.

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
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
db.collection("cities").whereEqualTo("state", "CA")
        .addSnapshotListener(MetadataChanges.INCLUDE) { querySnapshot, e ->
            if (e != null) {
                Log.w(TAG, "Listen error", e)
                return@addSnapshotListener
            }

            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")
            }
        }

Mendapatkan data offline

Jika Anda mendapatkan dokumen saat perangkat sedang offline, Cloud Firestore akan menampilkan data dari cache. Jika cache tidak berisi data untuk dokumen tersebut, atau dokumen tidak ada, panggilan 'get' akan menampilkan error.

Membuat kueri data offline

Pembuatan kueri berfungsi dengan persistensi data offline. Anda dapat mengambil hasil pembuatan kueri dengan cara mendapatkannya secara langsung atau dengan mendeteksinya, seperti yang dijelaskan di bagian sebelumnya. Anda juga dapat membuat kueri baru pada data yang disimpan secara lokal saat perangkat sedang offline, namun pada awalnya pembuatan kueri hanya akan berjalan pada dokumen yang disimpan dalam cache.

Menonaktifkan dan mengaktifkan akses jaringan

Anda dapat menggunakan metode di bawah ini untuk menonaktifkan akses jaringan untuk klien Cloud Firestore. Saat akses jaringan dinonaktifkan, semua pemroses foto dan dokumen meminta pengambilan hasil dari cache. Operasi tulis dimasukkan ke dalam antrean sampai akses jaringan diaktifkan kembali.

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
db.disableNetwork()
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                // Do offline things
                // ...
            }
        });
Kotlin
db.disableNetwork().addOnCompleteListener {
    // Do offline things
    // ...
}

Gunakan metode berikut untuk mengaktifkan kembali akses jaringan:

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
db.enableNetwork()
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                // Do online things
                // ...
            }
        });
Kotlin
db.enableNetwork().addOnCompleteListener {
    // Do online things
    // ...
}