I am trying to generate a document id to use on two documents in seperate collections.
I am able to achieve this in an Angular PWA, but I'm now working it into an iOS app.
Basically an appointment document is added to a user, then a top level document is created for ease of display and notifications using the same document id
users/uid/appointments/newID
appointments/uid/appointment/newID
All of this takes place in the same ViewController, so in the code I need to generate a temporary document id to use as the id in both collections.
I hope that makes sense....
would let tempId = db.document().documentID do the trick?
I managed to suss it all out.
After creating my collection reference, let's call it myRef, I did the following:
myRef = db.collection("collection_name")
secondRef = db.collection("second_collection")
let tempId = myRef.document().documentid
myRef.document(tempId).setData(myDictionary)
secondRef.document(tempId).setData(otherDictionary)
That helped create the duplicate document id's i needed.
Hope this helps with someone else...
Cheers
Michael
Related
Hello, I have a problem I created a Registration form and im trying to check if there is any user which have a certain username inside the Firebase Db. I tried to get the reference of all the users.
var users = Database.database().reference("users")
But I don't know how I could check if there is any user with a specified username.
You'll want to use a query for that. Something like:
let query = users.queryOrdered(byChild: "username").equalTo("two")
Then execute the query and check whether the result snapshot exists.
Note though that you won't be able to guarantee uniqueness in this way. If multiple users perform the check at the same time, they may both end up claiming the same user name.
To guarantee a unique user name, you will need to store the user names as the key - as keys are by definition unique within their parent node. For more on this, see some of these top search results and possibly also from here.
How can I create an array in firestore that can save external links?
I want to save the title and the href so that I can use both values in the read.
I want the links attribute to be an array so that I can save multiple links. Is it possible to do that in a single firebase attribute, or should I create separate link attributes with a href and title for each one (ie firstLinkTitle, firstLinkHref)?
It's not possible to have a number of links, that would be a different array - similar to an array of arrays.
The possibility for the creation of a field of type array for your documents, you can either use the console, where this type is available or via code as the following example:
const data = {
stringExample: 'Example',
arrayExample: ['Title', 'href']
};
const res = await db.collection('data').doc('one').set(data);
With the above example, you should be able to create a field of type array and set the data to it.
Besides that, if you want to update data from your array without uploading all the data again, you can use the function arrayUnion() or use the arrayRemove(), to remove elements from it.
You can get more information on how to work with arrays in Firestore, by checking the below documentation.
Add Data
In case you need something like nested arrays, indeed, you will need to have a "child" collection that will be linked to the father one.
Let me know if the information helped you!
I am trying to make a money related app which shows the user their spendings as a project to get used to Firebase. So I stumbled upon this issue; I can't seem to figure out how to add more than one expense assigned to a user. Whenever I add a new expense, the existing value in Firebase gets reset to the new value but I want it to store both the new and the old value. How can I do this?
There's something called "autoID" if that helps. I'll link that in a few moments.
Edit: It's used here.
childByAutoId() is what you want for swift. See Updating Or Deleting specific data section in the Read and Write Data on iOS
let thisUserRef = ref.child("users").child(users uid)
let expenseRef = thisUserRef.child("expenses").childByAutoId()
let dict = ["expense_type": "travel", "expense_amt": "1.99"]
expenseRef.setValue(dict)
will results in
users
uid_0
-Y88jn90skda //<- the node key created with childByAutoId
expense_type: "travel"
expense_amt: "1.99"
the childByAutoId is super powerful and allows 'random' node keys to be generated that contain your child data.
See the answer to this question and this other question for some tips on data modeling and queries.
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.
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.
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)
Few things here:
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.
While starting to work more with CloudKit I just realized that I don't actually know what a RecordID is...
I'm looking at the CloudKit dashboard right now, I see RecordTypes, RecordName etc, but I don't see RecordID. The iOS Dev library mentions RecordID a lot, but never actually tells what it is or where to find it.
I guess I'm just dumb, but I can't figure it out.
Every record has a record Id, which is a CKRecordID instance, and the class has a name property. If you don't specify a name, new records will have a record Id with a name that is a GUID.
You can only fetch with record Id if you know it, and in most instances you will let Cloud Kit create on for you, and you won't store it locally, so you won't know it.
Every CKRecord has a bunch of metadata, which includes the record id. See the list here.
Here a snapshot of the dashboard, your recognised it. You can either accept the recordIDs that CloudKit gives you or generate your own [although they must be unique within your database instance]. Here the screenshot
And here a small code snippet to show you how to create your own ID, using the same method I suspect CloudKit uses.
let uniqueReference = NSUUID().UUIDString
let uniqueRecordID = CKRecordID(recordName: uniqReference)
let newRecord = CKRecord(recordType: "Collection", recordID:uniqueRecordID)