如何使用 Swift 使用 Firebase 正确观察两个连接节点
Posted
技术标签:
【中文标题】如何使用 Swift 使用 Firebase 正确观察两个连接节点【英文标题】:How to properly observe two joined nodes with Firebase using Swift 【发布时间】:2017-05-28 18:34:12 【问题描述】:此问题源于此:Join different nodes to observe them at once with firebase。如果它非常相似,我深表歉意,但我正在努力在我的项目中解决它。
我有一个IngredientData,它获得了几种成分和一个属性:
"IngredientData":
"-KkY92MUZNHXxg4ivGY7":
"name": "Onions"
,
"-KkY90e7dAgefc8zH3_F":
"name": "Peas"
,
"-KkY9-HWJANdfhmD-SJ-":
"name": "Mushrooms"
,
"-KkbWdomTYdpgEDLjC9w":
"name": "Eggs"
,
"-KkbXOECSCBNAcVaO9rp":
"name": "Rice"
然后我有一个 RecipeData,其中包含 recipe 并且里面是 ingredients。
"RecipeData":
"-KlApwz5Y-TK_9z1sV1i":
"recipeName": "Fried Rice",
"ingredients":
"-KkbWdomTYdpgEDLjC9w": true,
"-KkbXOECSCBNAcVaO9rp": true,
"-KkY90e7dAgefc8zH3_F": true
我现在正在尝试获取配方中成分的详细信息,以便获取 name 属性。我有一个在配方成分中迭代的函数:
func fetchRecipeIngredients()
let databaseRef = FIRDatabase.database().reference().child("RecipeData/recipe/-KlApwz5Y-TK_9z1sV1i/ingredients")
databaseRef.observeSingleEvent(of: FIRDataEventType.value, with: snapshot in
for ingredients in snapshot.children
print(snapshot)
)
这是我的Recipe
课程:
class Recipe
var name: String!
var key: String
init(from snapshot: FIRDataSnapshot)
let snapshotValue = snapshot.value as! [String: Any]
self.name = snapshotValue["recipeName"] as! String
self.key = snapshot.key
我有两个主要问题:
首先,目前我不确定如何迭代特定配方,或者这对于我想要实现的目标是否必要。现在我已经对 recipeID 进行了硬编码,以便能够在其中进行迭代。
使用这个fetchRecipeIngredients()
时如何获取成分详情@
提前谢谢:)
【问题讨论】:
【参考方案1】:给你。
从 Firebase 结构开始
"IngredientData" :
"ingredient_0" :
"name" : "Onions"
,
"ingredient_1" :
"name" : "Peas"
,
"ingredient_2" :
"name" : "Mushrooms"
,
"ingredient_3" :
"name" : "Tomatoes"
,
"ingredient_4" :
"name" : "Dough"
,
"RecipeData" :
"recipe_0" :
"ingredients" :
"ingredient_0" : true,
"ingredient_1" : true,
"ingredient_2" : true
,
"name" : "Fried Rice"
,
"recipe_1" :
"ingredients" :
"ingredient_0" : true,
"ingredient_2" : true,
"ingredient_3" : true,
"ingredient_4" : true
,
"name" : "Pizza"
跟你的差不多
我们有一个加载特定配方的主函数,然后是加载成分的函数。
func loadRecipe()
let recipiesRef = self.ref.child("RecipeData")
let recipieToLoadRef = recipiesRef.child("recipe_1")
recipieToLoadRef.observeSingleEvent(of: .value, with: snapshot in
let recipieDict = snapshot.value as! [String:Any]
let name = recipieDict["name"] as! String
let ingredientsSnap = snapshot.childSnapshot(forPath: "ingredients")
print(name)
self.loadIngredients(ingredientSnap: ingredientsSnap)
)
func loadIngredients(ingredientSnap: DataSnapshot)
let ingredientsRef = self.ref.child("IngredientData")
for ingredient in ingredientSnap.children
let snap = ingredient as! DataSnapshot
let ingredientKey = snap.key
let thisIngredient = ingredientsRef.child(ingredientKey)
thisIngredient.observeSingleEvent(of: .value, with: snapshot in
let ingredientDict = snapshot.value as! [String: Any]
let ingredientName = ingredientDict["name"] as! String
print(" \(ingredientName)")
)
和输出
Pizza
Onions
Mushrooms
Tomatoes
Dough
编辑
回应后续评论:
如果您的用户想要存储他们的收藏夹,则创建一个节点
favorites
recipe_1: true
recipe_2: true
通过 .value 观察 /favorites 节点(这将一次读取他们所有的收藏夹。迭代快照中的子节点。键将是配方节点名称(recipe_1 和 recipe_2)。然后您可以加载每个直接来自节点的配方名称 (/recipe_1/name) 并填充一个数组,您可以将其用作 tableView 的数据源
【讨论】:
非常感谢您的回答,它运行良好。只有一个关于确定特定配方的问题。目前,我不得不在recipieToLoadRef
中硬编码该ID,以获取配方成分 的详细信息。但是,假设我想为用户创建一个favouriteList
以添加配方,我将如何指定要进入哪个配方然后显示在 tableView 之类的东西上?我已经尝试使用您为此所做的相同方法。如果这个问题无关紧要,请不要担心。再次感谢:)
@Chace 很高兴它有帮助!我用一些额外的信息更新了答案,以解决您的后续问题。
我很欣赏这个答案。我已经尝试过了,我能够打印出用户收藏夹中的食谱。但是,您可以直接从节点加载每个配方名称 (/recipe_1/name) 并填充可以用作 tableView 数据源的数组 的部分是我卡在的地方:/
@Chace 这里有很多关于堆栈溢出的示例,展示了如何从 Firebase 读取数据并填充数据源。我建议搜索这些,然后尝试一些代码。如果您遇到困难,请发布问题! (确保它不是重复的!)
@Chace 我的答案中的代码两者兼而有之;它获取配方并打印名称,然后获取成分并打印它们。如果您查看答案的底部,我会包含代码的输出;比萨是名字,成分是洋葱、蘑菇、西红柿和面团。以上是关于如何使用 Swift 使用 Firebase 正确观察两个连接节点的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Swift 中的 url 从 firebase 正确检索数据?
新的 Firebase 数据导致 TableView 单元格闪烁 (Firebase/iOS/Swift)