2016-04-29 3 views
11

firebaseにアイテムのリストを取得したいが、アイテムの各要素には関連アイテムのリストがある。私はfirebase-utilもファイヤーベースアレイ$extendの機能も使用していないので、リストを手に入れることはできませんでした。firebase配列内のアイテムリストの関連アイテムリストを取得する

私firebaseデータは次のようなものになります。

items 
    item1 
     name: "Item 1" 
     user: user1 
     images 
      image1: true 
      image2: true 
    item2 
     name: "Item 2" 
     user: user1 
     images: 
      image3: true 
      image4: true 
    item3 
     name: "Item 3" 
     user: user2 
     images: 
      image5: true 
      image6: true 

users 
    user1 
     name: "User 1" 
     email: "[email protected]" 
    user2 
     name: "User 2" 
     email: "[email protected]" 

images 
    image1 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    image2 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    image3 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    image4 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    image5 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 

をそして私は、すべてのデータを持つ項目のリストを取得したいです。次のようなものがあります:

items 
    item1 
     name: "Item 1" 
     user 
      name: "User 1" 
      email: "[email protected]" 
     images 
      image1 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 
      image2 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 
    item2 
     name: "Item 2" 
     user 
      name: "User 1" 
      email: "[email protected]" 
     images 
      image3 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 
      image4 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 
    item3 
     name: "Item 3" 
     user 
      name: "User 2" 
      email: "[email protected]" 
     images 
      image5 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 
      image6 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 

これはかなり一般的な使用例のようですが、私はここに固執しています。私は両方の方法でthisソリューションを試してみましたが、うまく動作しませんでした。私は別のリストの中にあるリストを関連付ける必要があるので、データ構造も少し異なります。

+0

それがあるとして、あなたはあなたに基づいて、あなたが求めているフォーマットでデータを取得することはできません。現在の構造。一度にすべてのデータを取得する理由についての情報を提供できますか?通常は、ユーザー名のリスト、またはアイテム3と一緒に表示されるイメージのリストを取得しますが、通常は一度にすべてではありません。あなたの質問には解決策があり、ユースケースが役立つと理解していると思います。 – Jay

+0

@Jayアイテムリストを表示したい。各アイテムにはイメージのリストがありますが、アイテムのメインピクチャとしてリストに表示されます。それで、なぜマウスオーバーで別のものに変更したいのですか?しかし、少なくとも私がそれを1つだけ行うことができれば、それはうまくいくでしょう。 – cor

答えて

2

おかげで、彼らは私の解決策は、両方のビットを持って、非常に参考にされています。私はそれをどのように理解したのか説明します。

まず、スキーマを変更し、アイテムのメイン画像の新しいキーを追加しました。私はそれをcoverと呼んだ。しかし、元の質問に答えると、私はそれをすべての画像を読み込みます。だからここに新しいitemsスキーマです:

items 
    item1 
     name: "Item 1" 
     user: user1 
     cover: image1 
     images 
      image1: true 
      image2: true 
    item2 
     name: "Item 2" 
     user: user1 
     cover: image3 
     images: 
      image3: true 
      image4: true 
    item3 
     name: "Item 3" 
     user: user2 
     cover: image5 
     images: 
      image5: true 
      image6: true 

その後、これは私が(asyncライブラリを使用して)上記のリストを取得する方法です。それは同じことを達成するためのより良いアプローチである可能性がありますよう

getItems: function(cb){ 
    var items = ref.child("items"); 
    items.on("value", function(snapshot){ 

     var item_length = snapshot.numChildren(), 
      final_items = [], 
      readed = 0; 

     ref.child("items").on("child_added", function(item){ 

      var item_id = item.key(), 
       itemData = item.val(), 

       user = ref.child("users").child(itemData.user), 
       cover = ref.child("images").child(itemData.cover), 
       images = new Firebase.util.NormalizedCollection(
         [ref.child("items").child(item_id).child("images"),'alertImages'], 
         ref.child('images') 
       ).select('images.image','images.thumb').ref(); 

       async.parallel([ 
        function(callback){ 
         user.on("value", function(user_snap){ 
          callback(null, user_snap.val()); 
         }); 
        }, 
        function(callback){ 
         images.on("value", function(images_snap){ 
          callback(null, images_snap.val()); 
         }); 
        }, 
        function(callback){ 
         cover.on("value", function(cover_snap){ 
          callback(null, cover_snap.val()); 
         }); 
        } 
       ], function(err, results){ 
        if(!!err){ 
         cb(err,null) 
        }else{ 
         itemData.user = results[0]; 
         itemData.images = results[1]; 
         itemData.cover = results[2]; 

         final_items.push(itemData); 
         readed += 1; 
         if(readed === item_length){ 
          cb(null,final_items); 
         } 
        } 
       }); 
     }); 
    }); 
} 

そして、これが出力されます何か:

item1 
    name: "Item 1" 
    cover: 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    user 
     name: "User 1" 
     email: "[email protected]" 
    images 
     image1 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
     image2 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
item2 
    name: "Item 2" 
    cover: 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    user 
     name: "User 1" 
     email: "[email protected]" 
    images 
     image3 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
     image4 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
item3 
    name: "Item 3" 
    cover: 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    user 
     name: "User 2" 
     email: "[email protected]" 
    images 
     image5 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
     image6 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
+0

あなたが解決してうれしいです。他の非同期呼び出し内の非同期呼び出しに注意してください。そうすれば、データが頻繁にチェックされることがあります。特に、push()といくつかのデバイスでほぼ同時にデータを読み書きすることができます。 – Jay

+0

アドバイスをいただき、ありがとうございました。@ Jay、コード構造だけでなく、答えのようなコードを探していました。現時点で私は何か良いものを見つけていません。私はやってみよう – cor

4

目的はアイテムリストを表示することです。

各項目には画像のリストがあります。

最初に、アイテムリストと各アイテムの画像の1つを表示します。アプローチを推奨

項目とその初期のサムネイルの一覧を移入するには、我々はから初期設定を引っ張る別のノードを持っている必要があります。

item_list_for_ui 
    random_node_0 
    item_id: "item_id_aa" 
    name: "Item 1" //if you want to display the name in the list 
    initial_thumb: "data:image/jpeg;base64,/9j/..." //initial thumb 
    link_to: "image1" 
    random_node_1 
    item_id: "item_id_xx" 
    name: "Item 2" 
    initial_thumb: "data:image/jpeg;base64,/9j/..." 
    link_to: "image3" 
    random_node_2 
    item_id: "item_id_qq" 
    name: "Item 3" 
    initial_thumb: "data:image/jpeg;base64,/9j/..." 
    link_to: "image1" 

アプリが起動し、移入:

更新されたアイテムのノードここ

items: 
    item_id_xx: //this should be a Firebase generated node name 
    name: "Item 2" 
    user: "uid_for_user_1" 
    images: 
    image3: "data:image/jpeg;base64,/9j/..." 
    image4: "data:image/jpeg;base64,/9j/..." 

は、ユーザーがより多くの詳細を取得するには、アイテム親指をクリックすることができ、メインリストのために使用されるノードですitems_list_for_uiノードのリスト。

ノードは浅く、Firebaseのitem_id、アイテム名(必要な場合)、初期イメージサムネイルを取得するためのリンク、Firebaseのメインイメージのlink_toが含まれています。例えば

:ユーザーが項目2のサムネイルをクリックすると、アイテムの詳細は

あなたがこの上で詳説する可能性があり

/アイテム/ item_id_xx /画像/画像3

で.VALUEでobserveSingleEventによってロードすることができますitem_list_for_ui

random_node_1 
    item_id: "item_id_xx" 
    name: "Item 2" 
    initial_thumb: "data:image/jpeg;base64,/9j/..." 
    thumb_link: "image3" 
    rollover_thumb: "external link to rollover" 
    rollover_link: "image4" 

に、たとえばロールオーバーのリンクを追加することにより、この構造は、その中であなたはちょうどそれらのそれぞれの子ノードを更新することにより、メインリストに表示したいものを親指とロールオーバー出て変更することができ、非常に柔軟です。

何百ものアイテムと何百もの子画像ノードの読み込みを避けることもできます。これらのノードと子ノードをすべて読み込むとuiがオーバーロードされることもあります。

この構造では、item_list_for_uiはコンパクトなので、何百ものアイテムであっても、そのデータの小さなサブセットです。

おそらく自分自身に言っているでしょう、それは重複データです。そうです.Firebaseでデータを複製するのは通常のプロセスです。構造がフラットに保たれ、クエリが作成され、データの処理がはるかに高速になります。あなたがあなたのイメージを通してあなたがループ可能性利用できるすべてのデータを持っており、残りのデータベース内のキーとしてそのメタデータを使用している場合

より読書について Denormalizing Data Keeps Your Breath Minty Fresh

+0

答えてくれてありがとうございます。しかし、あなたはどのようにデータに参加しますか? 'firebase-util'プラグインを使用しますか?もしそうなら、どうですか?アイテムIDが動的なので、関係をどうやって行うのか分かりません。 – cor

+0

@cor FirebaseにはSQLではないので、結合機能はありません。データを関連付けるにはいくつかの方法があり、Firebaseでデータを複製するのは問題ありません。私の答えはあなたの直接の質問に答えたと思います。あなたのコメント/フォローアップはすばらしい新しい質問です(そしてStackoverflow上で既にそれに対処するいくつかの答えがあります)。それらの回答をチェックし、特定の質問がある場合は投稿してください! – Jay

+0

申し訳ありませんが、あなたは正しいです – cor

2

を参照してください。

このように見えるオブジェクトの配列が得られるはず
var itemsArr = []; 
    for(var i in items) { 
     var item = items[i]; 
     var images = []; 
     for(var image in item[images]) { 
      item.push(images[image]); 
     } 
     itemsArr.push({ 
      name: item.name, 
      user: users[item.user], 
      images: images 
     }); 
    } 

:回答を@Jayと@Ericへ

{ 
    name: "Item 1", 
    user: { 
     name: "User 1", 
     email: "[email protected]" 
    }, 
    images: [{ 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
     },{ 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
    }] 
} 
+0

多くのおかげで@エリックN、あなたの答えは私が欲しかったもののために役立った – cor