Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기

데이터 읽기 및 쓰기

(선택 사항) 프로토 타입 및 중포 기지 에뮬레이터 스위트 룸과 테스트

중포 기지 에뮬레이터 스위트 룸 : 앱에서 읽고 실시간 데이터베이스에 기록하는 방법에 대해 이야기하기 전에, 당신이 프로토 타입 테스트 실시간 데이터베이스 기능하는 데 사용할 수있는 도구 세트를 소개하겠습니다. 서로 다른 데이터 모델을 시도하는 경우, 보안 규칙을 최적화하거나 좋은 아이디어가 될 수 라이브 서비스를 배포하지 않고 로컬에서 작업 할 수있는, 백 엔드와 상호 작용하기위한 가장 비용 효율적인 방법을 찾기 위해 노력.

실시간 데이터베이스 에뮬레이터뿐만 아니라 선택적으로 에뮬레이트 프로젝트 리소스 (기능, 다른 데이터베이스, 보안 규칙) .emulator_suite_short 에뮬레이트 데이터베이스 내용 및 구성과 상호 작용하여 응용 프로그램을 가능하게하는 에뮬레이터 제품군의 일부입니다

실시간 데이터베이스 에뮬레이터를 사용하면 몇 단계를 포함한다 :

  1. 앱의 테스트 설정에 코드의 라인을 추가하면 에뮬레이터에 연결합니다.
  2. 실행하는 로컬 프로젝트 디렉토리의 루트에서 firebase emulators:start .
  3. 평소와 같이 실시간 데이터베이스 플랫폼 SDK를 사용하거나 실시간 데이터베이스 REST API를 사용하여 응용 프로그램의 프로토 타입 코드에서 전화를 걸.

자세한 실시간 데이터베이스 및 클라우드 기능을 포함하는 연습 이 가능합니다. 또한 한 번 봐 가지고 있어야 에뮬레이터 스위트 소개 .

DatabaseReference 받기

읽기 또는 쓰기 데이터는 데이터베이스에서, 당신의 인스턴스가 필요합니다 DatabaseReference 를 :

DatabaseReference ref = FirebaseDatabase.instance.ref();

데이터 쓰기

이 문서는 읽기, 중포 기지 데이터를 작성의 기초를 다룹니다.

중포 기지 데이터가 기록된다 DatabaseReference 및 대기 또는 기준에 의해 방출 된 이벤트를 수신하여 검색. 이벤트 데이터의 초기 상태와 다시 언제든지 데이터 변경하면 방출된다.

기본 쓰기 작업

기본 쓰기 작업의 경우, 사용할 수있는 set() 해당 경로에서 기존 데이터를 대체 지정된 기준에 데이터를 저장합니다. 당신은 다음과 같은 유형에 대한 참조를 설정할 수 있습니다 : String , boolean , int , double , Map , List .

예를 들어,이있는 사용자 추가 할 수 있습니다 set() 다음과 같이 :

DatabaseReference ref = FirebaseDatabase.instance.ref("users/123");

await ref.set({
  "name": "John",
  "age": 18,
  "address": {
    "line1": "100 Mountain View"
  }
});

사용 set() 이런 식으로하면 자식 노드를 포함하여 지정된 위치에 데이터를 덮어 씁니다. 그러나 여전히 전체 개체를 다시 작성하지 않고 아이를 업데이트 할 수 있습니다. 당신은 사용자가 다음과 같이 사용자 이름을 업데이트 할 수있는 자신의 프로필을 업데이트 할 수 있도록하려는 경우 :

DatabaseReference ref = FirebaseDatabase.instance.ref("users/123");

// Only update the name, leave the age and address!
await ref.update({
  "age": 19,
});

update() 메서드를 사용하면 한 번에 데이터베이스에 여러 노드를 업데이트 할 수 있도록 노드에 하위 경로를 허용합니다

DatabaseReference ref = FirebaseDatabase.instance.ref("users");

await ref.update({
  "123/age": 19,
  "123/address/line1": "1 Mountain View",
});

데이터 읽기

값 이벤트를 수신하여 데이터를 읽기

사용, 경로에서 데이터를 읽고 변화를 들으려면 onValue 의 특성 DatabaseReference 을 수신하도록 DatabaseEvent 의.

당신은 사용할 수 있습니다 DatabaseEvent 를 이 이벤트의 시간에 존재하는, 주어진 경로에서 데이터를 읽을 수 있습니다. 청취자가, 때마다 다시 모든 어린이를 포함한 데이터를 부착하는 경우가 변경되면이 이벤트가 트리거됩니다. 이벤트는이 snapshot 하위 데이터를 포함하여 해당 위치에 모든 데이터를 포함하는 속성을. 데이터가없는 경우, 스냅 샷의는 exists 속성이 될 것입니다 false 과 그 value 의 속성은 null이 될 것입니다.

다음 예는 데이터베이스에서 게시물의 세부 사항을 검색하는 사회 블로깅 응용 프로그램을 보여줍니다

DatabaseReference starCountRef =
        FirebaseDatabase.instance.ref('posts/$postId/starCount');
starCountRef.onValue.listen((DatabaseEvent event) {
    final data = event.snapshot.value;
    updateStarCount(data);
});

수신기는 수신 DataSnapshot 그것의 이벤트시에 데이터베이스의 지정된 위치에 데이터가 포함 value 속성.

데이터 읽기 번

) (GET을 사용하면 읽기

SDK는 앱이 온라인 또는 오프라인인지 여부를 데이터베이스 서버와의 상호 작용을 관리 할 수 있도록 설계되었습니다.

일반적으로, 당신은 백엔드에서 데이터 업데이트에 대한 알림하려면 데이터를 읽는 기술은 위에서 설명한 값 이벤트를 사용해야합니다. 이러한 기술은 사용 및 결제를 줄이고, 그들이 온라인과 오프라인으로 사용자에게 최고의 경험을 제공하기 위해 최적화되어 있습니다.

한 번만 데이터를해야하는 경우 사용할 수 있습니다 get() 을 데이터베이스에서 데이터의 스냅 샷을 얻을 수 있습니다. 어떤 이유에 대한 경우 의 get() 서버 값을 반환 할 수없는 클라이언트는 로컬 스토리지 캐시를 조사하고 값이 여전히 발견되지 않는 경우 오류를 반환합니다.

다음 예는 사용자의 검색 보여줍니다 사용자 이름을 데이터베이스에서 하나의 시간 대중을 향한 :

final ref = FirebaseDatabase.instance.ref();
final snapshot = await ref.child('users/$userId').get();
if (snapshot.exists) {
    print(snapshot.value);
} else {
    print('No data available.');
}

불필요한 사용 get() 는 위와 같이 실시간 수신기를 이용하여 방지 할 수있는 성능의 손실, 대역폭 및 납의 사용을 증가시킬 수있다.

) (한 번 한 번에 데이터를 읽

로컬 캐시 대신 서버에서 업데이트 된 값에 대한 검사의 즉시 반환 할에서 경우에 따라 값을 할 수 있습니다. 이러한 경우에 당신은 사용할 수 있습니다 once() 하면 즉시 로컬 디스크 캐시에서 데이터를 얻을 수 있습니다.

이 한 번만로드해야하고 자주 변경하거나 적극적인 청취를 필요로 할 것으로 예상되지 않은 데이터에 유용합니다. 예를 들어, 앞의 예에서 블로깅 응용 프로그램은 새 게시물을 제작하기 시작 사용자의 프로파일을로드하려면이 방법을 사용합니다 :

final event = await ref.once(DatabaseEventType.value);
final username = event.snapshot.value?.username ?? 'Anonymous';

데이터를 업데이트 또는 삭제

업데이트 특정 필드

동시에 사용, 다른 자식 노드를 덮어 쓰지 않고 노드의 특정 아동에 쓸 update() 메소드.

호출 할 때 update() 트를 , 당신은 키에 대한 경로를 지정하여 낮은 수준의 하위 값을 업데이트 할 수 있습니다. 데이터를 더 확장하기 위해 여러 위치에 저장되어있는 경우, 당신은 사용하여 해당 데이터의 모든 인스턴스를 업데이트 할 수 있습니다 데이터 팬 아웃 . 예를 들어, 사회 블로깅 응용 프로그램은 게시물을 작성하고 동시에 최근 활동 피드 및 게시 사용자의 활동 피드를 업데이트 할 수 있습니다. 이렇게하려면 블로깅 응용 프로그램은 다음과 같은 코드를 사용합니다 :

void writeNewPost(String uid, String username, String picture, String title,
        String body) async {
    // A post entry.
    final postData = {
        'author': username,
        'uid': uid,
        'body': body,
        'title': title,
        'starCount': 0,
        'authorPic': picture,
    };

    // Get a key for a new Post.
    final newPostKey =
        FirebaseDatabase.instance.ref().child('posts').push().key;

    // Write the new post's data simultaneously in the posts list and the
    // user's post list.
    final Map<String, Map> updates = {};
    updates['/posts/$newPostKey'] = postData;
    updates['/user-posts/$uid/$newPostKey'] = postData;

    return FirebaseDatabase.instance.ref().update(updates);
}

이 예제 용도는 push() 에 모든 사용자의 게시물 포함 된 노드에 게시물 생성 /posts/$postid 을 동시에 가진 key 검색 키를 . 키는 다음에 사용자의 게시물에 두 번째 항목을 만드는 데 사용할 수 있습니다 /user-posts/$userid/$postid 을 .

이러한 경로를 사용하면 단일 호출로 JSON 트리의 여러 위치에 대한 동시 업데이트를 수행 할 수 있습니다 update() 등이 예는 두 위치에서 새 게시물을 작성하는 방법으로. 이 길을 동시 업데이트는 원자 있습니다 : 중 모든 업데이트가 성공하거나 모든 업데이트가 실패합니다.

완료 콜백을 추가

당신이 당신의 데이터가 커밋 된 때 알고 싶은 경우에, 당신은 완료 콜백을 등록 할 수 있습니다. 두 set()update() 반환 Future 의, 당신은 쓰기가 데이터베이스 언제 호출이 실패하기 위해 최선을 다하고되었을 때 호출되는 성공 및 오류 콜백을 첨부 할 수 있습니다.

FirebaseDatabase.instance
    .ref('users/$userId/email')
    .set(emailAddress)
    .then((_) {
        // Data saved successfully!
    })
    .catchError((error) {
        // The write failed...
    });

데이터 삭제

삭제 데이터에 대한 가장 간단한 방법은 호출하는 것입니다 remove() 를 데이터의 위치에 대한 참조하십시오.

당신은 또한 같은 다른 쓰기 작업에 대한 값으로 널 (null)을 지정하여 삭제할 수 있습니다 set() 또는 update() . 당신은이 기술을 사용할 수 있습니다 update() 단일 API 호출로 여러 아이들을 삭제합니다.

거래 등의 데이터 저장

이러한 증가 카운터 등의 동시 수정에 의해 손상 될 수있는 데이터로 작업 할 때, 당신이 거래 핸들러를 전달하여 트랜잭션을 사용할 수 있습니다 runTransaction() . 트랜잭션 처리기 인수로 데이터의 현재 상태를 소요하고 당신이 쓰기에하고 싶은 새로운 원하는 상태를 반환합니다. 새 값이 성공적으로 기록되기 전에 다른 클라이언트가 위치에 쓰는 경우 업데이트 기능은 새로운 현재 값으로 다시 호출하고, 쓰기가 시도됩니다.

예를 들어, 예를 들어 사회 블로깅 응용 프로그램, 당신은 사용자가 스타 및 별표 표시 취소 게시물과 다음 게시물이받은 얼마나 많은 별을 추적 할 수있는 :

void toggleStar(String uid) async {
  DatabaseReference postRef =
      FirebaseDatabase.instance.ref("posts/foo-bar-123");

  TransactionResult result = await postRef.runTransaction((Object? post) {
    // Ensure a post at the ref exists.
    if (post == null) {
      return Transaction.abort();
    }

    Map<String, dynamic> _post = Map<String, dynamic>.from(post as Map);
    if (_post["stars"] is Map && _post["stars"][uid] != null) {
      _post["starCount"] = (_post["starCount"] ?? 1) - 1;
      _post["stars"][uid] = null;
    } else {
      _post["starCount"] = (_post["starCount"] ?? 0) + 1;
      if (!_post.containsKey("stars")) {
        _post["stars"] = {};
      }
      _post["stars"][uid] = true;
    }

    // Return the new data.
    return Transaction.success(_post);
  });
}

기본적으로 이벤트는 여러 번 실행 기능을 실행할 수 있도록, 당신이 중간 상태를 볼 수 있습니다마다 트랜잭션 업데이트 기능 실행을 발생합니다. 당신은 설정할 수 있습니다 applyLocally 을 에 false 이벤트가 발생하기 전에 트랜잭션이 완료 될 때까지 이러한 중간 상태를 억제하고 대신 기다리는 :

await ref.runTransaction((Object? post) {
  // ...
}, applyLocally: false);

트랜잭션의 결과는이다 TransactionResult 해당 트랜잭션이 커밋 여부 등의 정보 등을 포함, 새로운 스냅 샷 :

DatabaseReference ref = FirebaseDatabase.instance.ref("posts/123");

TransactionResult result = await ref.runTransaction((Object? post) {
  // ...
});

print('Committed? ${result.committed}'); // true / false
print('Snapshot? ${result.snapshot}'); // DataSnapshot

거래 취소

당신이 안전하게 거래를 취소하고자하는 경우, 전화 Transaction.abort() 를 던져 AbortTransactionException 를 :

TransactionResult result = await ref.runTransaction((Object? user) {
  if (user !== null) {
    return Transaction.abort();
  }

  // ...
});

print(result.committed); // false

원자 서버 측 단위

/ 별 포스트 별표를 해제하는 사용자의 ID, 및 증가 된 스타 횟수 : 위 사용 사례에서 우리는 두 개의 데이터베이스에 값을 쓰고있어. 우리는 이미 사용자가 게시물을 주연 알고 있다면, 우리는 대신 트랜잭션의 원자 증가 작업을 사용할 수 있습니다.

void addStar(uid, key) async {
  Map<String, Object?> updates = {};
  updates["posts/$key/stars/$uid"] = true;
  updates["posts/$key/starCount"] = ServerValue.increment(1);
  updates["user-posts/$key/stars/$uid"] = true;
  updates["user-posts/$key/starCount"] = ServerValue.increment(1);
  return FirebaseDatabase.instance.ref().update(updates);
}

충돌하는 업데이트가 경우 자동으로 다시 실행하지 않도록이 코드는 트랜잭션 작업을 사용하지 않습니다. 증분 작업이 데이터베이스 서버에서 직접 발생하기 때문에, 충돌의 가능성이 없습니다.

당신이 감지하려는 그들은 이미 전에 출연 후 주연 같은 사용자로 응용 프로그램 별 충돌을 거부하는 경우 해당 사용 사례에 대한 사용자 정의 보안 규칙을 작성해야합니다.

데이터를 오프라인과 협력

클라이언트의 네트워크 연결이 끊어 경우, 응용 프로그램은 제대로 작동 나갈 것입니다.

중포 기지 데이터베이스에 연결된 모든 클라이언트는 활성 데이터 자체의 내부 버전을 유지합니다. 데이터가 기록 될 때, 그것은 먼저 로컬 버전에 기록합니다. 중포 기지의 클라이언트는 원격 데이터베이스 서버와는 "최선의 노력"에 기초하여 다른 클라이언트와 데이터를 동기화합니다.

모든 데이터가 서버에 기록되기 전에 결과, 모두, 지역 행사 즉시 데이터베이스 트리거에 기록합니다. 이 앱에 관계없이 네트워크 대기 시간 또는 연결의 반응 남아있는 것을 의미한다.

연결이 다시 설정되면, 앱이 사건의 적절한 설정을받을 수 있도록 사용자 지정 코드를 작성할 필요없이 현재 서버의 상태와 클라이언트 동기화.

우리는 오프라인의 행동에 대해 더 얘기하자 등에 대한 온라인 및 오프라인 기능 을 알아보세요 .

다음 단계