在单值上使用childByAutoId?

时间:2016-06-03 14:51:48

标签: swift firebase firebase-realtime-database

我对Swift和Firebase都很陌生,我正在尝试使用Firebase作为后端制作一个简单的应用程序。据我所知,没有内存有效的方法来使用numChildren()函数而不将每个子节点加载到内存中进行计数,所以我正在实现我自己的简单计数器来计算"事件"已在我的应用程序中创建。

Firebase的文档指出应该使用childByAutoID()方法来更新多用户应用程序中的列表。我假设它为请求的更新添加了一个时间戳,并按顺序执行。

我的问题是,当仅更新多用户应用程序中的SINGLE字段时是否有必要使用childByAutoID()。也就是说,如果我这样做,我的numEvents字段会发生冲突:

dbRef = FIRDatabase.database().reference()
dbRef.child("numEvents").setValue(num)

或者我必须这样做:

dbRef = FIRDatabase.database().reference()
dbRef.child("numEvents").childByAutoId().setValue(num)

为了避免写冲突?我唯一真正的困惑是childByAutoID的文档强调当子项是项目列表时它很有用,但我的只是一个项目。

3 个答案:

答案 0 :(得分:2)

如果您只更新单个字段,则不应使用childByAutoId。要更新对象的子值,您需要以某种方式获取对该对象的引用,可能通过某种类型的查询(在许多情况下,如果需要更改,您自然会有对该对象的引用)并且您可以改变这样的值:

dbRef.child("events").child(objectToUpdateId).child(fieldToUpdateKey).setValue(newValue)
在此上下文中,

childByAutoId将用于创建一个新字段,如:

dbRef.child("events").childByAutoId().setValue(newObject)

我不确定这如何适用于您的情况,但这些是如何更新字段的一些说明,并使用childByAutoId

答案 1 :(得分:1)

这里几件事:

  1. childByAutoId不是时间戳。但用于在任何给定节点中创建唯一节点。
  2. childByAutoId的使用案例:

    您有messages个节点,该节点存储来自参与群组聊天的多个用户的消息。因此,每个用户都可以在群聊中添加消息,这样每次用户发送消息时都会这样做:

    dbRef = FIRDatabase.database().reference()
    
    dbRef.child("messages").childByAutoId().setValue(messageText)
    

    因此,这将为来自不同用户的每条消息创建唯一的消息ID。这类似于普通数据库中消息的主键。

    数据库的结构将是这样的:

    messages: {
       "randomIdGenerated-12asd12" : "hello",
       "randomIdGenerated-12323D123" : "Hi, HOw are you",
    }
    

    所以在你的情况下,你的第一种方法已经足够了!由于您不需要唯一节点来计算添加的事件数。

答案 2 :(得分:1)

childByAutoId所做的是为节点创建一个唯一的密钥,以避免多次使用相同的密钥,然后创建数据冲突,如不一致(而不是写冲突),以避免使用事务块的写冲突。

最好的学习方法是尝试

如果num == 1,在第一个例子中结果将是

dbRef:{
  numEvents:1
}

第二个将是

dbRef:{
  numEvents:{
    //The auto-generated key
    KLBHJBjhbjJBJHB:1
  }  
}

如果要在节点中保存多个相同类型的子节点,那么childByAutoId会很有用,这样每个子节点都有自己唯一的标识符

例如

pet:{
  KJHBJJHB:{
    name:fluffy,
    owner:John Smith,
  },
  KhBHJBJjJ:{
    name:fluffy,
    owner:Jane Foster,
  }
} 

通过这种方式,您可以获得一个唯一的标识符,用于项目数据没有明确的方式以确保它是唯一的(在这种情况下是宠物的名字)