如何正确构建 Firebase 数据库以方便读取和删除

Posted

技术标签:

【中文标题】如何正确构建 Firebase 数据库以方便读取和删除【英文标题】:How to properly structure Firebase database to allow easy reading and removal 【发布时间】:2016-09-12 20:04:10 【问题描述】:

我正在创建一个食谱查找应用程序,基本上我有一个“收藏夹”,如果用户喜欢一个食谱,他们将能够在应用程序的收藏夹选项卡中轻松访问它。基本上这是我现在的结构:

app:
 users:
  2ReAGRZlYiV5F2piwMakz59XDzl1(uid):
   favorites:
    -KRUe6mMhaQOX62zgXvg(childByAutoId):
     ID: 172171 (recipe id)
  UTJ0rVst9zMSuQhWkikTCu8558C2(uid):
   favorites:
    -KRUzMxTvv-uNvX9J9_-(childByAutoId):
     ID: 578141 (recipe id)

基本上,每当他们进入“收藏夹”选项卡时,我都需要所有食谱 ID 的列表,以便我可以调用 API 来检索食谱信息。我基本上是在遍历字典。我还希望能够允许用户取消收藏食谱,因此将其从数据库中删除。如果我正在使用,我将如何删除它:

USERS_REF.child(uid).child("favorites").childByAutoId().setValue(["ID": recipeID])

添加食谱?

我可以使用更好的结构来读取配方 ID 并轻松删除它们吗?

【问题讨论】:

【参考方案1】:

您可能想考虑将收藏夹设为NSDictionary:-

 app:
  users:
   2ReAGRZlYiV5F2piwMakz59XDzl1: //(uid)
    favorites:
      172171 : true,
        4123123 : true,.. 

对于收藏夹中的追加:-

  USERS_REF.child(uid).child("favorites").updateChildValues([recipeID: "true"]) 

请注意,如果您的 recipeID 是唯一的,即在收藏夹节点中不存在 只有这样它才会追加值,如果 recipieID 已经存在,它只会更新它的值(不喜欢这个追加,查找下一个选项)

或者

let prntRef = USERS_REF.child(uid).child("favorites")
prntRef.observeSingleEventOfType(.Value, withBlock:  (snap) in

    if let favDict = snap.value as? NSMutableDictionary
        favDict.setObject("true",forKey : recipeID)
        prntRef.setValue(favDict) 
     else 
        prntRef.setValue(["true":recipeID])
    
)

对于收藏夹中的更新:-

 USERS_REF.child(uid).child("favorites").updateChildValues([recipeID: "false"])  //User doesn't like's the recipe anymore

对于从收藏夹中删除:-

 USERS_REF.child(uid).child("favorites").child(recipeID).removeValue()  //User want to remove this item from its history

同时检索

 let prntRef = USERS_REF.child(uid).child("favorites")
 prntRef.observeSingleEventOfType(.Value, withBlock: (snap) in

     if let favDict = snap.value as? [String:AnyObject]

         for each in favDict

             let eachRecipeId = each.0 //recipeID
             let isMyFav = each.1 // Bool
         

      else 
         print("No favourites")
     
)

同时检索已知key-value

 let prntRef = USERS_REFFIR.child("users").queryOrderedByChild("favorites/\(recipeID)").queryEqualToValue(true)
 prntRef.observeSingleEventOfType(.Value, withBlock: (snap) in

     //snap containing all the Users that carry that recipeID in their favourite section 
 )

【讨论】:

即使 id 是假的,保持 id 在那里不是很理想吗? 这样你就可以跟踪你的用户是否喜欢那个特定的接收者。是的。这也将帮助您构建应用的推荐引擎 基本上当我想阅读最喜欢的食谱时,我必须循环浏览所有的食谱,对吗? 是的,您必须遍历,但是如果您知道要查找的 recipeID,您可以轻松地使用queryOrderedByChild(recipeID) 查找它。存储为字典是一个好习惯 :) 快乐编码 对不起,你能解释一下如何使用 queryOrederedByChild(recipeID) 吗?

以上是关于如何正确构建 Firebase 数据库以方便读取和删除的主要内容,如果未能解决你的问题,请参考以下文章

用户扫描二维码以读取和写入特定数据库节点后如何在 Firebase 中设置安全规则

如何以正确的方式从 firebase 数据库加载图像

Firebase 数据结构建模以消除冗余更新或删除

从 Firebase 检索和读取数据作为 NSArray (Swift 3)

如何以正确的方式读取组件内的 redux 状态?

如何使用 HTTP 请求触发 Firebase 函数以从多个节点读取数据?