如何使用Swift正确观察两个使用Firebase的加入节点

如何使用Swift正确观察两个使用Firebase的加入节点

问题描述:

此问题跟从此:Join different nodes to observe them at once with firebase。我很抱歉,如果它非常相似,但我正努力在我的项目中解决它。如何使用Swift正确观察两个使用Firebase的加入节点

我有一个IngredientData其获得几种成分和一个属性:

{ 
    "IngredientData": { 
    "-KkY92MUZNHXxg4ivGY7": { 
     "name": "Onions" 
    }, 
    "-KkY90e7dAgefc8zH3_F": { 
     "name": "Peas" 
    }, 
    "-KkY9-HWJANdfhmD-SJ-": { 
     "name": "Mushrooms" 
    }, 
    "-KkbWdomTYdpgEDLjC9w": { 
     "name": "Eggs" 
    }, 
    "-KkbXOECSCBNAcVaO9rp": { 
     "name": "Rice" 
    } 
    } 
} 

我然后有一个RecipeData包含配方和内部是成分

{ 
    "RecipeData": { 
    "-KlApwz5Y-TK_9z1sV1i": { 
     "recipeName": "Fried Rice", 
     "ingredients": { 
     "-KkbWdomTYdpgEDLjC9w": true, 
     "-KkbXOECSCBNAcVaO9rp": true, 
     "-KkY90e7dAgefc8zH3_F": true 
     } 
    } 
    } 
} 

我现在想进去配方成分的细节,所以我可以得到财产。我有一个函数,配方的成分里迭代:

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 
    } 
} 

我有2个主要问题:

  1. 首先,在我不知道如何通过一个特定的配方迭代,或者如果这对我想实现的目标是必要的。现在我已经对recipeID进行了硬编码,以便能够在其中进行迭代。

  2. 提前使用该fetchRecipeIngredients()

感谢时,我如何获得成分的细节:)

在这里你去。

与火力地堡结构

{ 
    "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数据源的数组。

+0

非常感谢您的回答,它完美地工作。关于识别特定配方只是一个问题。目前,我必须在'recipieToLoadRef'中硬编码_ID_以获得配方的_reredients_的详细信息。然而,假设我想为用户创建一个'favouriteList'来添加配方,我将如何指定要使用的配方,然后显示类似于tableView的东西?我尝试过使用与此相同的方法。如果这个问题不相关,那么不要担心。再次感谢:) – Chace

+0

@Chace很高兴帮助!我更新了一些附加信息的答案,以解决您的后续问题。 – Jay

+0

我很感激这个答案。我已经尝试过这一点,并且能够在用户收藏夹内打印出食谱。然而,_You然后可以直接从节点加载每个配方名称的部分(/ recipe_1/name)并填充一个可用作tableView_的数据源的数组,这就是我被卡在的地方:/ – Chace