Ikuti semua informasi yang diumumkan di Firebase Summit, dan pelajari bagaimana Firebase dapat membantu Anda mempercepat pengembangan aplikasi dan menjalankan aplikasi dengan percaya diri. Pelajari Lebih Lanjut

Akses data offline

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Cloud Firestore mendukung persistensi data offline. Fitur ini menyimpan salinan data Cloud Firestore yang digunakan aplikasi Anda secara aktif, sehingga aplikasi Anda dapat mengakses data tersebut saat perangkat offline. Anda dapat menulis, membaca, mendengarkan, dan menanyakan data yang di-cache. Saat perangkat kembali online, Cloud Firestore menyinkronkan setiap perubahan lokal yang dibuat oleh aplikasi Anda ke backend Cloud Firestore.

Untuk menggunakan persistensi offline, Anda tidak perlu melakukan perubahan apa pun pada kode yang Anda gunakan untuk mengakses data Cloud Firestore. Dengan persistensi offline diaktifkan, pustaka klien Cloud Firestore secara otomatis mengelola akses data online dan offline serta menyinkronkan data lokal saat perangkat kembali online.

Konfigurasikan kegigihan offline

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

  • Untuk platform Android dan Apple, persistensi offline diaktifkan secara default. Untuk menonaktifkan persistensi, setel opsi PersistenceEnabled ke false .
  • Untuk web, persistensi offline dinonaktifkan secara default. Untuk mengaktifkan persistensi, panggil metode enablePersistence . Cache Cloud Firestore tidak otomatis dihapus di antara sesi. Akibatnya, jika aplikasi web Anda menangani informasi sensitif, pastikan untuk menanyakan kepada pengguna apakah mereka menggunakan perangkat tepercaya sebelum mengaktifkan persistensi.

Web version 9

import { enableIndexedDbPersistence } from "firebase/firestore"; 

enableIndexedDbPersistence(db)
  .catch((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

Web version 8

firebase.firestore().enablePersistence()
  .catch((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
Cepat
Catatan: Produk ini tidak tersedia di target watchOS dan App Clip.
let settings = FirestoreSettings()
settings.isPersistenceEnabled = true

// Any additional options
// ...

// Enable offline data persistence
let db = Firestore.firestore()
db.settings = settings
Objective-C
Catatan: Produk ini tidak tersedia di target watchOS dan App Clip.
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+KTX

val settings = firestoreSettings {
    isPersistenceEnabled = true
}
db.firestoreSettings = settings

Dart

// Apple and Android
db.settings = const Settings(persistenceEnabled: true);

// Web
await db
    .enablePersistence(const PersistenceSettings(synchronizeTabs: true));

Konfigurasikan ukuran cache

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

Web version 9

import { initializeFirestore, CACHE_SIZE_UNLIMITED } from "firebase/firestore";

const firestoreDb = initializeFirestore(app, {
  cacheSizeBytes: CACHE_SIZE_UNLIMITED
});

Web version 8

firebase.firestore().settings({
    cacheSizeBytes: firebase.firestore.CACHE_SIZE_UNLIMITED
});
Cepat
Catatan: Produk ini tidak tersedia di target watchOS dan App Clip.
// 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
Catatan: Produk ini tidak tersedia di target watchOS dan App Clip.
// 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+KTX


// 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

Dart

db.settings = const Settings(
  persistenceEnabled: true,
  cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED,
);

Dengarkan data offline

Saat perangkat offline, jika Anda telah mengaktifkan kegigihan offline, pendengar Anda akan menerima peristiwa mendengarkan saat data yang di-cache secara lokal berubah. Anda dapat mendengarkan 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 true , data berasal dari cache dan mungkin basi atau tidak lengkap. Jika fromCache false , data lengkap dan terkini dengan pembaruan terbaru di server.

Secara default, tidak ada acara yang dimunculkan jika hanya SnapshotMetadata yang diubah. Jika Anda mengandalkan nilai fromCache , tentukan opsi mendengarkan includeMetadataChanges saat Anda melampirkan pengendali pendengar Anda.

Web version 9

import { collection, onSnapshot, where, query } from "firebase/firestore"; 

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

        const source = snapshot.metadata.fromCache ? "local cache" : "server";
        console.log("Data came from " + source);
    });
});

Web version 8

db.collection("cities").where("state", "==", "CA")
  .onSnapshot({ includeMetadataChanges: true }, (snapshot) => {
      snapshot.docChanges().forEach((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);
      });
  });
Cepat
Catatan: Produk ini tidak tersedia di target watchOS dan App Clip.
// 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
Catatan: Produk ini tidak tersedia di target watchOS dan App Clip.
// 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+KTX

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

Dart

db
    .collection("cities")
    .where("state", isEqualTo: "CA")
    .snapshots(includeMetadataChanges: true)
    .listen((querySnapshot) {
  for (var change in querySnapshot.docChanges) {
    if (change.type == DocumentChangeType.added) {
      final source =
          (querySnapshot.metadata.isFromCache) ? "local cache" : "server";

      print("Data fetched from $source}");
    }
  }
});

Dapatkan data offline

Jika Anda mendapatkan dokumen saat perangkat offline, Cloud Firestore mengembalikan data dari cache.

Saat menanyakan koleksi, hasil kosong dikembalikan jika tidak ada dokumen yang di-cache. Saat mengambil dokumen tertentu, kesalahan dikembalikan sebagai gantinya.

Kueri data offline

Kueri berfungsi dengan ketekunan offline. Anda dapat mengambil hasil kueri dengan pengambilan langsung atau dengan mendengarkan, seperti yang dijelaskan di bagian sebelumnya. Anda juga dapat membuat kueri baru pada data yang disimpan secara lokal saat perangkat offline, tetapi kueri awalnya hanya akan dijalankan terhadap dokumen yang di-cache.

Konfigurasikan indeks kueri offline

Secara default, Firestore SDK memindai semua dokumen dalam koleksi di cache lokalnya saat menjalankan kueri offline. Dengan perilaku default ini, kinerja kueri offline dapat menurun saat pengguna offline untuk jangka waktu yang lama.

Platform Apple , Android , dan JavaScript SDK menyediakan metode setIndexConfiguration yang memungkinkan Anda mengonfigurasi indeks kueri lokal untuk meningkatkan kinerja kueri offline Anda.

Metode ini membaca konfigurasi terstruktur JSON yang sama yang digunakan untuk mengonfigurasi indeks di server, mengikuti format definisi indeks yang sama .

Konfigurasi indeks offline yang akan digunakan bergantung pada koleksi dan dokumen mana yang sering diakses aplikasi Anda saat offline dan kinerja offline yang Anda inginkan. Meskipun Anda dapat mengekspor konfigurasi indeks backend untuk digunakan pada klien, pola akses offline aplikasi Anda kemungkinan besar berbeda secara signifikan dari pola akses online, sehingga konfigurasi indeks online Anda mungkin tidak cocok untuk digunakan secara offline. Koleksi dan dokumen mana yang Anda ingin aplikasi Anda akses offline dengan performa tinggi? Setelah Anda menganalisis perilaku aplikasi, ikuti prinsip definisi indeks dari panduan pengindeksan .

Agar konfigurasi indeks offline tersedia untuk dimuat di aplikasi klien Anda:

  • kompilasi dan distribusikan dengan aplikasi Anda
  • unduh dari CDN
  • ambil dari sistem penyimpanan seperti Cloud Storage for Firebase .

Nonaktifkan dan aktifkan akses jaringan

Anda dapat menggunakan metode di bawah ini untuk menonaktifkan akses jaringan untuk klien Cloud Firestore Anda. Saat akses jaringan dinonaktifkan, semua pendengar snapshot dan permintaan dokumen mengambil hasil dari cache. Operasi tulis diantrekan hingga akses jaringan diaktifkan kembali.

Web version 9

import { disableNetwork } from "firebase/firestore"; 

await disableNetwork(db);
console.log("Network disabled!");
// Do offline actions
// ...

Web version 8

firebase.firestore().disableNetwork()
    .then(() => {
        // Do offline actions
        // ...
    });
Cepat
Catatan: Produk ini tidak tersedia di target watchOS dan App Clip.
Firestore.firestore().disableNetwork { (error) in
    // Do offline things
    // ...
}
Objective-C
Catatan: Produk ini tidak tersedia di target watchOS dan App Clip.
[[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+KTX

db.disableNetwork().addOnCompleteListener {
    // Do offline things
    // ...
}

Dart

db.disableNetwork().then((_) {
  // Do offline things
});

Gunakan metode berikut untuk mengaktifkan kembali akses jaringan:

Web version 9

import { enableNetwork } from "firebase/firestore"; 

await enableNetwork(db);
// Do online actions
// ...

Web version 8

firebase.firestore().enableNetwork()
    .then(() => {
        // Do online actions
        // ...
    });
Cepat
Catatan: Produk ini tidak tersedia di target watchOS dan App Clip.
Firestore.firestore().enableNetwork { (error) in
    // Do online things
    // ...
}
Objective-C
Catatan: Produk ini tidak tersedia di target watchOS dan App Clip.
[[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+KTX

db.enableNetwork().addOnCompleteListener {
    // Do online things
    // ...
}

Dart

db.enableNetwork().then((_) {
  // Back online
});