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

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

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

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

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

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

Q&A

解決済

1回答

514閲覧

firebaseのobserveSingleEventの挙動について [swift]

kou009

総合スコア16

Firebase

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

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

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

0グッド

0クリップ

投稿2018/05/25 12:16

FirebaseのRealTimeDatabaseを利用しています。
FirebaseObserveSingleEventの挙動に関して質問があります。

observeSingleEvent内で、test1,test2,test1,test2,test1という順番でログを出したいです。

[行いたい挙動。]
snapshot.key test1
snapshot.key test2
snapshot.key test1
snapshot.key test2
snapshot.key test1

[実際の挙動]
snapshot.key test1
snapshot.key test1
snapshot.key test1
snapshot.key test2
snapshot.key test2

説明がわかりずらいかと思いますので、実際の挙動のログを画像で添付します。
このような順番でログが出ます。
イメージ説明

補足:var userIds: [String] = ["test1","test2", "test3", "test4" , "test5"]
という風にすべて違う文字列にすると、ちゃんと"test1","test2", "test3", "test4" , "test5"の順番でログが出ます。

![イイメージ説明(37ca001dd2ef25d0045852fef9d5dcdb.png)

どのようにすれば、observeSingleEvent内で、test1,test2,test1,test2,test1という順番でログを出せるでしょうか?

Swift

1  var REF_USERS = Database.database().reference().child("users") 2 var userIds: [String] = ["test1","test2","test1","test2" ,"test1"] 3// var userIds: [String] = ["test1","test2", "test3", "test4" , "test5"] 4 5 override func viewWillAppear(_ animated: Bool) { 6 for userId in userIds { 7 print("userId (userId)") 8 REF_USERS.child(userId).observeSingleEvent(of: .value, with: { 9 snapshot in 10 print("snapshot.key (snapshot.key)") 11 }) 12 } 13 }

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

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

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

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

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

guest

回答1

0

ベストアンサー

observeSingleEventは、非同期でDBにアクセスしデータを取得するメソッドです。ご質問内のコードのように同時に複数の処理を呼ぶ場合は並列処理となるので、結果の返ってくる順序は必ずしも順番通りにはなりません。

さらに、RealtimeDBでは一度アクセスしたデータへのアクセス時にはキャッシュが効くので、結果が早く返ってきます。 ["test1","test2","test1","test2","test1"] の場合に結果が test1, test1, test1, test2, test2 となるのはそのためです。

配列の順番通りにアクセスして結果を受け取るようにしたいのなら、非同期処理を直列でつなぐようにすればOKです。つまり、1つ目のデータが返ってきた時点で2つ目のデータへのアクセスを行う、…(以下同様)という風に書きます。

swift

1// コード例 2 3override func viewWillAppear(_ animated: Bool) { 4 super.viewWillAppear(...) 5 6 getUsers(remainUserIds: userIds) 7} 8 9func getUsers(remainUserIds: [String]) { 10 guard let userId = remainUserIds.first else { 11 return 12 } 13 14 REF_USERS.child(userId).observeSingleEvent(of: .value, with: { snapshot in 15 print("snapshot.key (snapshot.key)") 16 17 // remainUserIdsから先頭を削除して、次の処理を呼ぶ 18 getUsers(remainUserIds: Array(remainUserIds.dropFirst())) 19 }) 20}

配列なので再帰的な書き方にしてみました。Promiseなどのライブラリを使えばもっとスッキリと書けると思います。

投稿2018/05/26 04:03

kakajika

総合スコア3131

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

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

kou009

2018/05/27 08:21

ありがとうございます。教えていただいたコードで解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問