5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Firebase Firestoreから特定のフィールドの値を取得する(Angularfire)

Last updated at Posted at 2020-04-22

#こっちを参考したほうが簡単かと。。。
追記!(2020/11月)
Firestoreから特定のフィールドの値を取得する最も簡単な方法(Angular)
:point_up::sweat_smile:

#はじめに
Firebaseのデータベース、Cloud Firestoreで特定のフィールドの値だけ取得したい場合がありますよね?

例えば、このデータベースで言うとusersコレクションの中の特定のユーザーのeventCountの値を取りたい場合。
スクリーンショット 2020-04-20 17.47.49.jpg

この場合、どうすればいいか?
よく見かけるのは以下のようなやり方
https://firebase.google.com/docs/firestore/query-data/get-data?hl=ja

var docRef = db.collection("cities").doc("SF");

docRef.get().then(function(doc) {
    if (doc.exists) {
        console.log("Document data:", doc.data());
    } else {
        console.log("No such document!");
    }
}).catch(function(error) {
    console.log("Error getting document:", error);
});

get()を使えばいいんだろ??

そう思うかもしれない。しかし!!!
Angularfireではこのサンプル通りにいかないのだ!!!

#前提条件
Angularfireがプロジェクトに入っていること

#解決策

home.page.ts
import { map, take, pluck } from 'rxjs/operators';
import { User } from 'src/app/auth/auth.service';
import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-my-page',
  templateUrl: './home.page.html',
  styleUrls: ['./home.page.scss'],
})
export class MyPagePage implements OnInit {
  currentUser: User;

  private userDoc: AngularFirestoreDocument<User>;
  $user: Observable<User>;

  constructor(
    private afAuth: AngularFireAuth,
    private db: AngularFirestore,
  ) {  }

  ngOnInit() {
    this.afAuth.auth.onAuthStateChanged((user) => {
      if (user != null) {
        this.userDoc = this.db.doc<User>(`users/${user.uid}`);
        this.$user = this.userDoc.valueChanges();
        return (this.$user = this.userDoc.snapshotChanges().pipe(
          map((snap) => {
            const data = snap.payload.data();
            // ここのeventCountがフィールドの値!
            console.log('僕の' + data.eventCount);
            const id = snap.payload.id;
            return { id, ...data };
          })
        ));
      }
    });
  }

}

なぜかhtmlページにこれが無いと、何も取得できない。。。
view側で表示する必要がない場合は、cssで言うところのdisplay: none;などを使って見えなくすれば問題ない・・・

home.page.html
   <h2>{{ ($user | async)?.eventCount }}</h2>

ちなみにauth.service.tsで定義されてるUserはこんな感じ

auth.service.ts
export interface User {
  uid: string;
  email: string;
  displayName?: string;
  myCustomData?: string;
  photoURL?: string;
  eventCount?: number;
}

#なぜかget()が使えない問題
結論、get()は使えるみたい!

詳しくはこちらを見て欲しい。
要約するとAngularFirestoreDocument<{}>get()を持っておらず、AngularFirestoreDocument<{}>.refの形にすると、get()が使えるようになるんだとか。。

this.db.collection("cities")
               .doc("SF")
               .ref
               .get().then(function(doc) {
                   if (doc.exists) {
                       console.log("Document data:", doc.data());
                   } else {
                       console.log("No such document!");
                   }
               }).catch(function(error) {
                   console.log("Error getting document:", error);
               });

が、今回取得したいのが特定のフィールドの値である。
これでは1つのドキュメントを取得しているだけで、そのドキュメント内のフィールドの値だけを取得はできていない。。。

doc.data()の後に何かをつければ取得できるのだろうが、発見できなかったです。。。情報提供お待ちしております。:sweat_smile:

#参考
https://stackoverrun.com/ja/q/13092622

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?