🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2978閲覧

[swift 5]Cast from 'DocumentReference' to unrelated type 'String' always fails

Kaguya_4869

総合スコア117

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/11/16 10:01

編集2019/11/18 09:20

#質問したいこと
現在firebaseを使ったアプリを作成しています。前回の質問の時にもあった相手側が設定したパスワードと自分が入力したパスワードが一致した場合にログインできるようにするというところで前回とは違う
Cast from 'DocumentReference' to unrelated type 'String' always fails
というエラーが出てきました。画面遷移をする時にも落ちてしまうのでおそらくここが問題なのではないのかと思います。
#コード

swift5

1import UIKit 2import Firebase 3import FirebaseAuth 4 5class AccountViewController: UIViewController, UITextFieldDelegate { 6 var acount: FirebaseApp! 7 8 var database: Firestore! 9 10 var saveData: UserDefaults = UserDefaults.standard 11 12 13 @IBAction private func didTapSignUpButton() { 14 let email = emailTextField.text ?? "" 15 let password = passwordTextField.text ?? "" 16 let name = nameTextField.text ?? "" 17 let groupname = groupnameTextField.text ?? "" 18 19 20 let dataname: String = database.collection("group").document("groupname") as! String 21 let datapassword: String = database.collection("group").document("groupname") as! String 22 if dataname == groupnameTextField.text && datapassword == passwordTextField.text{ 23 Auth.auth().createUser(withEmail: email, password: password) { [weak self] result, error in 24 guard let self = self else { return } 25 if let user = result?.user { 26 let req = user.createProfileChangeRequest() 27 req.displayName = name 28 req.commitChanges() { [weak self] error in 29 guard let self = self else { return } 30 if error == nil { 31 user.sendEmailVerification() { [weak self] error in 32 guard let self = self else { return } 33 if error == nil { 34 // 仮登録完了画面へ遷移する処理 35 // サインアップ完了のフラグを保持する 36 UserDefaults.standard.set(true, forKey: "appSignUpStatusKey") 37 UserDefaults.standard.synchronize() 38 } 39 self.showErrorIfNeeded(error) 40 } 41 } 42 self.showErrorIfNeeded(error) 43 } 44 } 45 self.showErrorIfNeeded(error) 46 } 47 // サインアップ完了のフラグを保持する 48 UserDefaults.standard.set(true, forKey: "appSignUpStatusKey") 49 // ユーザー名を保存する 50 UserDefaults.standard.set(name, forKey: "userNameKey") 51 UserDefaults.standard.synchronize() 52 53 } 54 } 55 56 57 private func showErrorIfNeeded(_ errorOrNil: Error?) { 58 // エラーがなければ何もしません 59 guard let error = errorOrNil else { return } 60 let message = "エラーが起きました" // ここは後述しますが、とりあえず固定文字列 61 let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert) 62 alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) 63 present(alert, animated: true, completion: nil) 64 } 65 66} 67

swift5

1//エラーが出ている箇所 2let dataname: String = database.collection("group").document("groupname") as! String 3 let datapassword: String = database.collection("group").document("groupname") as! String 4 if dataname == groupnameTextField.text && datapassword == passwordTextField.text{ 5// 6// 7// 8}

#エラー
Cast from 'DocumentReference' to unrelated type 'String' always fails

追記

エラーがでる部分イメージ説明

まだfirebaseを使い始めたばかりなので、丁寧に教えてくださると嬉しいです。

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

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

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

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

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

hayabusabusash

2019/11/16 10:15

database.collection("group").document("groupname") は String ではなく DocumentReferenceが返ってくるので、それを String で強制キャストしようとしてエラーになっているんだと思います。 もしFirestoreの"group"コレクション内のドキュメントを取得したい場合は getDocumentsメソッドを使うと取得できると思います。 Firestoreにどんなデータがあって、何が取り出したいのかを追記していただければより詳しく回答できると思います????‍♂️
Kaguya_4869

2019/11/16 11:19

firebaseには相手側で設定したパスワードとグループ名が入っています。それら2つのデータを取り出したいです。
hayabusabusash

2019/11/16 11:40

なるほど。 ドキュメントの名前は"groupname"で固定でしょうか? あと、パスワードとグループ名が入っているフィールドの名前を教えていただけませんか?
Kaguya_4869

2019/11/17 03:30 編集

ドキュメントの名前はグループ名の方がgroupnameで、パスワードの方がgrouppasswordです。(わかりにくくてすみません????‍♂️) パスワードが入っているフィールド名はgrouppasswordで グループ名が入っているフィールド名はgroupnameです。
guest

回答1

0

ベストアンサー

ドキュメントの名前はグループ名の方がgroupnameで、パスワードの方がgrouppasswordです。

パスワードが入っているフィールド名はgrouppasswordで
グループ名が入っているフィールド名はgroupnameです。

こちらの情報ありがとうございます。
そうなるとFirestoreのデータの構造はこんな感じでしょうか?(間違っていたらすみません...)

group( Collection ) └ groupname( Document ) ├ groupname( Field ) └ grouppassword( Field )

groupnameドキュメントをFirestoreから取得して、
grouppasswordgroupnameを表示するならこんな感じになると思います。

Swift

1 2let db = Firestore.firestore() 3 4// groupnameドキュメントを取得 5db.collection("group") 6 .document("groupname") 7 .getDocument { (documentSnapshot, error) in 8 if let error = error { 9 print(error) 10 } 11 12 // ドキュメントの内容を取り出す 13     if let data = documentSnapshot?.data() { 14 let groupName = data["groupname"] as? String 15 let groupPassword = data["grouppassword"] as? String 16 17 print("Group name: (groupName)") 18 print("Group password: (groupPassword)") 19 } 20}

とりあえず両方ともString?にしておきました。
Firestoreの構成が違ったり、フィールド名が違ったりしたら教えてください????‍♂️

2019/11/17追記(コードを追加する場所について)

didTapSignUpButton()の中でいいと思います。
非同期処理が続くので、selfのキャプチャーに気をつけてください。(参考)

Swift

1@IBAction private func didTapSignUpButton() { 2 let email = emailTextField.text ?? "" 3 let password = passwordTextField.text ?? "" 4 let name = nameTextField.text ?? "" 5 let groupname = groupnameTextField.text ?? "" 6 7 // ここに追加 8 database.collection("group") 9 .document("groupname") 10 .getDocument { [weak self] (documentSnapshot, error) in 11 guard let self = self else { return } 12 13 if let error = error { 14 print(error) 15 } 16 17 // ドキュメントの内容を取り出す 18 if let data = documentSnapshot?.data() { 19 // 強制キャストにしました 20 let storedGroupName = data["groupname"] as! String 21 let storedGroupPassword = data["grouppassword"] as! String 22 23 // Firestore側のデータとテキストフィールドの値を比較 24 if groupname == storedGroupName && password == storedGroupPassword { 25 // Authの処理 26 Auth.auth().createUser(withEmail: email, password: password) { [weak self] result, error in 27 guard let self = self else { return } 28 29 // 後の処理は同じなので省略します 30 } 31 } 32 } else { 33 // Firestore側のgroupNameとgroupPasswordが一致しない時の処理 34 } 35 } 36}

一応質問に貼っていただいたコードと変数名とかを合わせたつもりですが、
動かなかったりしたら教えてください????‍♂️

投稿2019/11/17 07:32

編集2019/11/18 11:27
hayabusabusash

総合スコア767

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

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

Kaguya_4869

2019/11/17 08:32

ありがとうございます。私がまだまだ未熟でそのコードをどこに入れてみたらいいのかわかりません。 とりあえず入れてみたんですが、どこにコードを書けば教えていただけますか?
hayabusabusash

2019/11/17 14:12

コードを追加する位置について追記しました!
hayabusabusash

2019/11/18 11:29

すみません、documentSnapshotはオプショナルなので documentSnapshot?.data()になりますね。修正しました。
Kaguya_4869

2019/11/18 13:01

ありがとうございます! できました!本当にありがとうございます!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問