在 firebase 数组中检索项目列表的相关项目列表
Retrieve a related item list of an item list in a firebase array
我想获取 firebase 中的项目列表,但项目的每个元素都有相关项目的列表。我无法获得列表,也没有使用 firebase-util nor firebase array $extend 功能。
我的 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: "user1@email.com"
user2
name: "User 2"
email: "user2@email.com"
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: "user1@email.com"
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: "user1@email.com"
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: "user2@email.com"
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/..."
这看起来像是一个相当常见的用例,但我被困在这里了。我已经尝试了 解决方案(两种方式),但我无法让它工作。数据结构也有点不同,因为我需要关联另一个列表中的列表。
objective是显示项目列表。
每个项目都有一个图像列表。
最初,显示项目列表和每个项目的图像之一。
建议的方法:
要填充项目列表及其初始缩略图,我们需要有一个单独的节点,我们从中提取初始设置。
更新项目节点
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/..."
这是用于主列表的节点,用户可以在其中单击项目缩略图以获取更多详细信息:
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_list_for_ui 节点填充列表。
该节点很浅,包含 Firebase item_id、项目名称(如果需要)、link(从中获取初始图像缩略图)以及 link_to Firebase 中的主图像。
例如:如果用户点击项目 2 的缩略图,则可以通过 observeSingleEvent 加载项目详细信息,值为
/items/item_id_xx/images/image3
您可以通过在 item_list_for_ui
中添加翻转 link 来阐述这一点
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 中复制数据是一个正常的过程,并且受到鼓励:它使结构更平坦,并使查询和处理数据的速度更快。
如果您拥有所有可用数据,您可以循环浏览图像并将其元数据用作数据库其余部分中的键。
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
});
}
这应该会产生一个如下所示的对象数组:
{
name: "Item 1",
user: {
name: "User 1",
email: "user1@email.com"
},
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/..."
}]
}
感谢@Jay 和@Eric 的回答,他们非常有帮助,我的解决方案两者兼而有之。我会解释我是怎么想出来的。
首先,我更改了架构并为项目的主图片添加了一个新键。我将其命名为 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: "user1@email.com"
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: "user1@email.com"
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: "user2@email.com"
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/..."
我想获取 firebase 中的项目列表,但项目的每个元素都有相关项目的列表。我无法获得列表,也没有使用 firebase-util nor firebase array $extend 功能。
我的 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: "user1@email.com"
user2
name: "User 2"
email: "user2@email.com"
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: "user1@email.com"
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: "user1@email.com"
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: "user2@email.com"
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/..."
这看起来像是一个相当常见的用例,但我被困在这里了。我已经尝试了
objective是显示项目列表。
每个项目都有一个图像列表。
最初,显示项目列表和每个项目的图像之一。
建议的方法:
要填充项目列表及其初始缩略图,我们需要有一个单独的节点,我们从中提取初始设置。
更新项目节点
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/..."
这是用于主列表的节点,用户可以在其中单击项目缩略图以获取更多详细信息:
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_list_for_ui 节点填充列表。
该节点很浅,包含 Firebase item_id、项目名称(如果需要)、link(从中获取初始图像缩略图)以及 link_to Firebase 中的主图像。
例如:如果用户点击项目 2 的缩略图,则可以通过 observeSingleEvent 加载项目详细信息,值为
/items/item_id_xx/images/image3
您可以通过在 item_list_for_ui
中添加翻转 link 来阐述这一点 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 中复制数据是一个正常的过程,并且受到鼓励:它使结构更平坦,并使查询和处理数据的速度更快。
如果您拥有所有可用数据,您可以循环浏览图像并将其元数据用作数据库其余部分中的键。
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
});
}
这应该会产生一个如下所示的对象数组:
{
name: "Item 1",
user: {
name: "User 1",
email: "user1@email.com"
},
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/..."
}]
}
感谢@Jay 和@Eric 的回答,他们非常有帮助,我的解决方案两者兼而有之。我会解释我是怎么想出来的。
首先,我更改了架构并为项目的主图片添加了一个新键。我将其命名为 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: "user1@email.com"
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: "user1@email.com"
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: "user2@email.com"
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/..."