0

I am pretty new to both Swift and Firebase, and I am attempting to make a simple app using Firebase as the backend. As far as I know, there is no memory-efficient way to use the numChildren() function without loading every single child into memory for counting, so I am implementing my own simple counter for the number of "Events" that have been created in my app.

The documentation for Firebase states that the childByAutoID() method should be used for updating lists in multi-user applications. I am assuming it adds a timestamp to the requested update and does them in order.

My question is whether it is necessary to use childByAutoID() when only updating a SINGLE field in a multi-user application. That is, will there be conflicts on my numEvents field if I do:

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

Or must I do:

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

In order to avoid write conflicts? My only real confusion is that the documentation for childByAutoID stresses that it is useful when the children are a list of items, but mine is only a single item.

Avery B
  • 237
  • 1
  • 11

3 Answers3

2

If you are only updating a single field you should not be using childByAutoId. To update a child value for an object, you need to obtain a reference to that object somehow, perhaps by a query of some sort (in many cases you will naturally already have a reference to the object if it needs to be changed) and you can change the value like this:

dbRef.child("events").child(objectToUpdateId).child(fieldToUpdateKey).setValue(newValue)

childByAutoId in this context would be used to create a new field like:

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

I'm not exactly sure how this applies to your situation, but those are some descriptions of how to update a field, and use childByAutoId.

rigdonmr
  • 2,662
  • 3
  • 26
  • 40
1

Few things here:

  1. childByAutoId is not a timestamp. But is used to create unique nodes in any given node.

Use case of childByAutoId :

You have messages node which stores messages from multiple user who are involved in a group chat. So each user can add messages in the group chat so you would do something like this each time user sends message:

dbRef = FIRDatabase.database().reference()

dbRef.child("messages").childByAutoId().setValue(messageText)

So this will create a unique message id for each message from different users. This will kind of act like primary key of message in normal databases.

The structure of database will be something like this:

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

So in your case your first approach is good enough! Since you dont need unique node for counting number of events added.

Prajeet Shrestha
  • 7,978
  • 3
  • 34
  • 63
  • While `childByAutoId` is not a timestamp it is based off of a timestamp, which allows for them to be chronologically ordered – David East Jun 03 '16 at 15:11
1

What childByAutoId does is create a unique key for a node, to avoid using the same key multiple times and then creating data conflicts like inconsistency (not write conflicts) to avoid write conflicts you use the transaction blocks.

The best way to learn is to try it out

If num == 1 , in the first example the result will be

dbRef:{
  numEvents:1
}

While the second will be

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

The childByAutoId would be useful if you want to save in a node multiple children of the same type, that way each children will have its own unique identifier

For example

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

This way you have a unique identifier for cases where there is no clear way with the item data to guarantee it will be unique (in this case the pet's name)

Ymmanuel
  • 2,523
  • 13
  • 12