質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1689閲覧

firebase(v9)の公式ドキュメントに載っているgetDocの実装例を参考に実装すると エラー([exists is not a function])が発生。解消方法を知りたい。

yuki_20211108

総合スコア14

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2022/03/20 02:34

編集2022/03/21 00:22

前提・実現したいこと

React(Redux)+firebaseの認証機能を使ってログイン処理を行った後に
画面上にサインイン情報を表示させようとしています。

下記動画を参考にしながら学習しているところです。
https://www.youtube.com/watch?v=PNvLGoop8z8&t=2340s

発生している問題・エラーメッセージ

firebaseのv9でドキュメント情報を取得する処理を実装していたのですが、
データが取得できず下記エラーが出てしまいます。
「Uncaught (in promise) TypeError: snapshot.exists is not a function at operations.js:29:1」

該当コードは以下になります。

JavaScript

1import {signInAction} from './actions'; 2import {push} from 'connected-react-router'; 3import {auth, db} from '../../firebase/index' 4import { doc,getDoc } from 'firebase/firestore'; 5import { 6 signInWithEmailAndPassword 7} from 'firebase/auth' 8 9export const signIn = (email,password) => { 10 return async (dispatch) => { 11 // Validation 12 if (email === "" || password === "") { 13 alert("必須項目が未入力です") 14 return false 15 } 16 17 signInWithEmailAndPassword(auth,email,password) 18 .then(result => { 19 const user = result.user 20 21 if(user) { 22 const uid = user.uid 23 console.log("uid:",uid) 24 25 const docRef = doc(db,"users",uid) 26 const snapshot = getDoc(docRef) 27 28 if (snapshot.exists()) { 29 console.log("snapshot:",snapshot); 30 const data = snapshot.data() 31 dispatch(signInAction({ 32 isSignedIn: true, 33 role: data.role, 34 uid: uid, 35 username: data.username 36 })) 37 } else { 38 console.log("No Such document!:"); 39 } 40 41 dispatch(push('/')) 42 } 43 }) 44 } 45}

firebaseの公式ドキュメントも参考にしながら実装していたのですが、
エラーの解消方法がわからず困っているところです・・・。
https://firebase.google.com/docs/firestore/query-data/get-data?hl=ja#get_a_document

試したこと

[確認1]
上記コードの中でuidを出力する処理を入れて、問題なく取れていることは確認できています。
イメージ説明
イメージ説明

[確認2]
snapshot変数の中身を確認してみましたが、コンソール出力をしてみた限りでは存在しているように見えます。
イメージ説明

[確認3]
下記の記事を参考にgetDoc関数の処理後に[.then]を付けて実装してみたところ、ドキュメント情報を取得できた。
https://reffect.co.jp/react/react-crud-firebase-9

JavaScript

1getDoc(docRef).then((snapshot) => { 2 console.log(snapshot.exists()) 3 console.log(snapshot.data()) 4})

イメージ説明

[確認4]
改めて公式ドキュメントを参考として愚直にgetDocの前にawaitを付けてみたが、別のエラーが出てしまう(awaitの使い方に問題がありそう?)。
「Parsing error: Unexpected reserved word 'await'」
signInWithEmailAndPassword(XXX).then(result => {...})という実装のところで[result]の前に[async]を付けると上記エラーが解消されて、求めている処理結果になった。
イメージ説明

補足情報(FW/ツールのバージョンなど)

firebase:9.6.6
React:17.0.2
React-redux:7.2.6
npm:8.1.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mike2mike4

2022/03/20 03:57

snapshot変数取れてますか?
yuki_20211108

2022/03/20 05:22

snapshot変数の中身を確認してみましたが、コンソール出力を実施してみた限りでは取れているようには見えます・・・。
mike2mike4

2022/03/20 06:45

あとは、 import { doc,getDoc } from 'firebase/firestore'; を import { doc,getDoc } from 'firebase/compat/firestore'; にしてみるとか
hoshi-takanori

2022/03/20 07:10

getDoc は非同期関数のようなので、await する必要があるのでは…。
guest

回答1

0

自己解決

mike2mike4さん、hoshi-takanoriさんのサポートにより無事求めている処理結果を出すことができました。完全には理解できていませんが、連携してくださった情報を整理すると主に2パターンの実装方法があるようです。

.then/async&awaitの使い方も理解しながら学習を進めていきたいと思います。
独力では解決方法がわからず困っていたところなので、とても助かりました!
ありがとうございましたm(_ _)m!

<求めていた処理結果(ブラウザ)>
イメージ説明

<実現方法>

JavaScript([.thenを使う場合])

1signInWithEmailAndPassword(auth,email,password) 2 .then(result => { 3 const user = result.user 4 5 if(user) { 6 const uid = user.uid 7 const docRef = doc(db,"users",uid) 8 9 getDoc(docRef).then((snapshot) => { 10 if (snapshot.exists()) { 11 const data = snapshot.data() 12 dispatch(signInAction({ 13 isSignedIn: true, 14 role: data.role, 15 uid: uid, 16 username: data.username 17 })) 18 } else { 19 console.log("No Such document!:"); 20 } 21 }) 22 23 dispatch(push('/')) 24 } 25 })

JavaScript([async/await]を使う場合)

1signInWithEmailAndPassword(auth,email,password) 2 .then(async (result) => { 3 const user = result.user 4 5 if(user) { 6 const uid = user.uid 7 const docRef = doc(db,"users",uid) 8 const snapshot = await getDoc(docRef) 9 10 if (snapshot.exists()) { 11 const data = snapshot.data() 12 dispatch(signInAction({ 13 isSignedIn: true, 14 role: data.role, 15 uid: uid, 16 username: data.username 17 })) 18 } else { 19 console.log("No Such document!:"); 20 } 21 22 dispatch(push('/')) 23 } 24 })

投稿2022/03/21 00:35

yuki_20211108

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問