콘솔로 이동

오프라인 데이터 사용 설정

Cloud Firestore는 오프라인 데이터 지속성을 지원합니다. 이 기능은 기기가 오프라인 상태일 때 앱에서 데이터에 액세스할 수 있도록 앱에서 자주 사용하는 Cloud Firestore 데이터의 사본을 캐시합니다. 캐시된 데이터를 쓰고, 읽고, 수신 대기하고, 쿼리할 수 있습니다. 기기가 다시 온라인 상태가 되면 Cloud Firestore는 앱의 로컬 변경사항을 Cloud Firestore에 원격으로 저장된 데이터에 동기화합니다.

오프라인 지속성을 사용하기 위해 Cloud Firestore 데이터에 액세스할 때 사용하는 코드를 변경할 필요는 없습니다. 오프라인 지속성을 사용 설정하면 Cloud Firestore 클라이언트 라이브러리는 온라인 및 오프라인 데이터 액세스를 자동으로 관리하고 기기가 다시 온라인 상태가 되면 로컬 데이터를 동기화합니다.

오프라인 지속성 구성

Cloud Firestore를 초기화할 때 오프라인 지속성을 사용 설정하거나 중지할 수 있습니다.

  • Android 및 iOS에서는 오프라인 지속성이 기본적으로 사용 설정됩니다. 지속성을 사용 중지하려면 PersistenceEnabled 옵션을 false로 설정하세요.
  • 웹에서는 오프라인 지속성이 기본적으로 사용 중지됩니다. 지속성을 사용 설정하려면 enablePersistence 메소드를 호출하세요. Cloud Firestore의 캐시는 세션 간에 자동으로 삭제되지 않습니다. 따라서 웹 앱에서 중요한 정보를 처리하는 경우 지속성을 사용 설정하기 전에 신뢰할 수 있는 기기인지 사용자에게 확인해야 합니다.
firebase.initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  projectId: '### CLOUD FIRESTORE PROJECT ID ###',
}
);

firebase.firestore().enablePersistence()
  .then(function() {
      // Initialize Cloud Firestore through firebase
      var db = firebase.firestore();
  })
  .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
          // ...
      }
  });
  
Android
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
        .setPersistenceEnabled(true)
        .build();
db.setFirestoreSettings(settings);
  
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;
  

오프라인 데이터 수신 대기

오프라인 지속성을 사용 설정한 경우 기기가 오프라인 상태이면 로컬에 캐시된 데이터가 변경될 때 리스너가 수신 대기 이벤트를 수신합니다. 문서, 컬렉션, 쿼리를 수신 대기할 수 있습니다.

데이터의 출처가 서버인지 아니면 캐시인지 확인하려면 스냅샷 이벤트의 SnapshotMetadata에 있는 fromCache 속성을 사용합니다. fromCachetrue이면 캐시에서 가져온 데이터이므로 서버와 일치하지 않거나 불완전할 수 있습니다. fromCachefalse이면 서버의 최신 업데이트와 일치하는 완전한 최신 데이터입니다.

기본적으로 SnapshotMetadata 변경되면 이벤트가 발생하지 않습니다. fromCache 값을 중요하게 참고하는 경우 수신 대기 핸들러를 연결할 때 includeMetadataChanges 수신 대기 옵션을 지정하세요.

db.collection("cities").where("state", "==", "CA")
  .onSnapshot({ includeQueryMetadataChanges: 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);
      });
  });
 
Android
db.collection("cities").whereEqualTo("state", "CA")
        .addSnapshotListener(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);
                }

            }
        });
Swift
// Listen to metadata updates to receive a server snapshot even if
// the data is the same as the cached data.
let options = QueryListenOptions()
options.includeQueryMetadataChanges(true)

db.collection("cities").whereField("state", isEqualTo: "CA")
    .addSnapshotListener(options: options) { 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.
FIRQueryListenOptions *options = [FIRQueryListenOptions options];
[options includeQueryMetadataChanges:YES];
[[[db collectionWithPath:@"cities"] queryWhereField:@"state" isEqualTo:@"CA"]
    addSnapshotListenerWithOptions:options
    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);
    }];
  

오프라인 데이터 가져오기

기기가 오프라인 상태일 때 문서를 가져오면 Cloud Firestore는 캐시의 데이터를 반환합니다. 캐시에 해당 문서의 데이터가 없거나 문서가 존재하지 않으면 가져오기 호출은 오류를 반환합니다.

오프라인 데이터 쿼리

쿼리는 오프라인 지속성과 연동합니다. 앞에서 설명한 것처럼 직접 가져오기 또는 수신 대기를 통해 쿼리 결과를 검색할 수 있습니다. 기기가 오프라인 상태일 때 로컬에 유지되는 데이터에 대해 새 쿼리를 만들 수도 있지만, 이러한 쿼리는 처음에는 캐시된 문서에 대해서만 실행됩니다.