How to Add Document with Custom Id to Firebase (Firestore) on Swift

How to add Document with Custom ID to firestore

To use a custom ID you need to use .set, rather than .add

This creates a document with the ID "LA":

db.collection("cities").doc("LA").set({
name: "Los Angeles",
state: "CA",
country: "USA"
})

This is taken from the official docs here

How to add Document with Custom ID to Firebase (Firestore) on Swift

Yes. Just try this:

Firestore.firestore().collection("items").document("yourId").setData(["item": "test"]) 

Add a Document's Document ID to Its Own Firestore Document - Swift 4

While there is a perfectly fine answer, FireStore has the functionality you need built in, and it doesn't require two calls to the database. In fact, it doesn't require any calls to the database.

Here's an example

    let testRef = self.db.collection("test_node")
let someData = [
"child_key": "child_value"
]

let aDoc = testRef.document() //this creates a document with a documentID
print(aDoc.documentID) //prints the documentID, no database interaction
//you could add the documentID to an object etc at this point
aDoc.setData(someData) //stores the data at that documentID

See the documentation Add a Document for more info.

In some cases, it can be useful to create a document reference with an
auto-generated ID, then use the reference later. For this use case,
you can call doc():

You may want to consider a slightly different approach. You can obtain the document ID in the closure following the write as well. So let's give you a cool Ride (class)

class RideClass {
var availableSeats: Int
var carType: String
var dateCreated: String
var ID: String

init(seats: Int, car: String, createdDate: String) {
self.availableSeats = seats
self.carType = car
self.dateCreated = createdDate
self.ID = ""
}

func getRideDict() -> [String: Any] {
let dict:[String: Any] = [
"availableSeats": self.availableSeats,
"carType": self.carType,
"dateCreated": self.dateCreated
]
return dict
}
}

and then some code to create a ride, write it out and leverage it's auto-created documentID

    var aRide = RideClass(seats: 3, car: "Lincoln", createdDate: "20190122")

var ref: DocumentReference? = nil
ref = db.collection("rides").addDocument(data: aRide.getRideDict() ) { err in
if let err = err {
print("Error adding document: \(err)")
} else {
aRide.ID = ref!.documentID
print(aRide.ID) //now you can work with the ride and know it's ID
}
}

making document ID = UID firestore swift

Instead of addDocument, which uses a random ID, use build a DocumentReference to the document you want to create, and use setData to create it.

db
.collection("users")
.document(results!.user.uid)
.setData(...)

I suggest reading the documentation for more information about creating documents.

Swift Firebase Custom Object with Document ID

There is an even easier way to achieve this using the Codable support we added to Firestore recently:

Add the FirebaseFirestoreSwift pod:

# Uncomment the next line to define a global platform for your project
platform :ios, '13.0'

target 'MyAwesomeApp' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!

# Pods for MyAwesomeApp
pod 'Firebase/Analytics'
pod 'Firebase/Firestore'
pod 'FirebaseFirestoreSwift'
end
import FirebaseFirestoreSwift
struct City: Codable, Identifiable {
@DocumentID var id: String? = UUID().uuidString
let name: String
let state: String
let country: String
let isCapital: Bool
let population: Int64

// you only need CodingKeys if your attribute names in Firestore differ from the property names on your struct!
}

By using the @DocumentID property wrapper, you tell Firestore's Codable support that you want it to map the document's ID to the id field. Also note that - as the City struct implements Identifiable - you will be able to use it in a SwiftUI ListView.

Then, in your view model, use queryDocumentSnapshot.data(as:) to fetch and map data in a typesafe way:

import FirebaseFirestore

class CitiesViewModel: ObservableObject {
@Published var cities = [City]()

private var db = Firestore.firestore()
private var listenerRegistration: ListenerRegistration?

deinit {
unregister()
}

func unregister() {
if listenerRegistration != nil {
listenerRegistration?.remove()
}
}

func fetchData() {
unregister()
listenerRegistration = db.collection("cities").addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}

self.cities = documents.compactMap { queryDocumentSnapshot -> City? in
return try? queryDocumentSnapshot.data(as: City.self)
}
}
}
}

How do I map my ViewModel's ID to the Document ID in Firestore?

I recommend using Codable to map your Firestore documents to Swift structs. This will make your code easier to write, less prone to errors, and more type-safe.

Specifically, it will also enable you to use @DocumentID to map the Firestore document ID to the id attribute of your Swift struct.

Here's a quick example:

struct Book: Codable {
@DocumentID var id: String?
var title: String
var numberOfPages: Int
var author: String
}

func fetchBook(documentId: String) {
let docRef = db.collection("books").document(documentId)
docRef.getDocument { document, error in
if let error = error as NSError? {
self.errorMessage = "Error getting document: \(error.localizedDescription)"
}
else {
if let document = document {
do {
self.book = try document.data(as: Book.self)
}
catch {
print(error)
}
}
}
}
}

For more details, see this comprehensive guide I wrote about mapping Firestore documents to Swift structs (and back).

For more information about how to delete a Firestore document from a SwiftUI app, check out this article



Related Topics



Leave a reply



Submit