How to get Firestore document ID marshalled into struct? - firebase

I want to fetch a document from Firestore and have it marshalled into my custom struct. Currently all data is unmarshalled, but I can't find a way to get the document ID into my struct. Here is an example:
type MyStruct struct {
ID string // What to put here?
PropA string `firestore:"prop_a"`
PropB string `firestore:"prop_b"`
}
doc, err := client.Doc(docref).Get(ctx) // Fetch document
var x MyStruct // Allocate object
err = doc.DataTo(&x) // Unmarshal
The result is that PropA and PropB are populated on x, but I have no idea how to populate the ID field with the document ID.
I can obviously just manually fish it out of doc, but it feels like DataTo should be able to handle this.

The id is not part of the document data. Assign it as you mentioned:
x.ID = doc.Ref.ID

Related

Firebase: Removing an Object from an Array

i'm trying to delete an specific object from an array in Firestore via SwiftUI. The following function deletes the whole watchlist. What am I missing?
func removeFromWatchlist() {
if let uid = Auth.auth().currentUser?.uid {
let docRef = db.collection("user").document(uid) // company.symbol = "AAPL"
docRef.updateData(["watchlist": FieldValue.arrayRemove([company.symbol])]) { error in
if error == nil {
print("Successful deleted array")
}
}
}
}
And here is my Firestore structure:
To remove an item from an array with FieldValue.arrayRemove you must specify the exact, complete data that is stored in the array.
Assuming your company.symbol is AAPL, the call FieldValue.arrayRemove([company.symbol] removes that exact string from the array - not the AAPL key that you have with an object under it.
You'll have to read the entire array from the document into you application code, remove it there, and then write the entire modified array back to the document.

How to insert a reference type field on Firestore with Golang

Inside my database i'm using fields of reference type on some documents, like this:
I'm trying to insert these property on firestore
_, err = userReference.Set(context.Background(), models.User{
Jobs: []*firestore.DocumentRef{employeeReference},
})
On this case I used an array of *DocumentRef, but even if is a unique DocumentRef doesn't work, I also tried to insert as type DocumentRef instead of the pointer, and also doesn't work, my User type is like that:
type User struct {
Jobs []*firestore.DocumentRef `json:"jobs"`
}
There's something that I can do to insert this type of data from go? On Javascript SDK, I remember that is only to insert the DocumentReference type directly on object that is achieved, but I'm facing this problem with Golang.
I have no experience with Golang but here you can find many examples.
I wonder if something like the following can give you any hints:
_, err := userReference.Set(context.Background(), models.User{
Jobs: []*firestore.DocumentRef{client.Doc("/selfManagedEmployees/K4qhd5k1c...")}
})

How do i find value from the collection value of the array by comparing ID in firebase on snapshot in React-native?

I have a collection called doctors. I need to find only that data from collection which has current user inside the allParticipants
ex:
doctors.allParticipants.userID == userID
As you can see in the allParticipants has array of data
is there any way to find this data using where condition or any else please help me to figure out this
You can use array-contains operator however you need to know the complete user object for that as it's an array of object and not strings. For example,
const userObj = {
channel: "/channels/channelId",
user: "/users/userId",
userID: "userId"
}
const colRef = firebase.firestore().collection("channels")
colRef.where("allParticipants", "array-contains", userObj).get().then(snap => {
console.log(`${snap.size} documents found`)
})
If you could store an array of userID (string) only, then the query would be as easy as:
const {uid} = firebase.auth().currentUsers.uid
const query = colRef.where("participantUIDs", "array-contains", uid)
But if you need to keep that array of objects, then you'll first need to fetch that user's channel ID and follow method 1.

Handling a Firestore map object in Swift 5

I was struggling yesterday to handle in a SWIFT app a Firestore map object that had a variable size so I though to share my solution.
The document contained a map like this:
{"07:45"=9;"09:56"=4;"13:12"=16}
The problem was that there could be more or less fields and the field names are unknown in advance, so it was not possible to know how many elements there were or even the names of the fields. For this reason I couldn't address the fields directly by just reading it into a dictionary. On top of that, as dictionaries is not ordered, I couldn't just address the elements in the dictionary by index.
I solved this by first reading the map into a dictionary, sorting it into an array, and then addressing the index of the array I wanted.
db.document(eventID).getDocument{ (document, error) in
if let document = document, document.exists {
let let data = document.data()
let timeslots = data!["times"] as! Dictionary<String, Int>
let self.count = timeslots.count. // To use elsewhere
let sortedTimes = self.timeslots.sorted(by: { $0.0 < $1.0 }) // Sort by key value which contains times as strings.
print(sortedTimes[0].value) // Just to print the value of the first tuple. NB sortedTimes is an Array of key,value pairs.
} else {
print("Document does not exist")
}
}

Firestore - Fetch Subcollection Swift

Converting from Firebase to Firestore
I have a database that looks like the following
Above is a Firebase node for entries in a photo album. The top level node is the ID of the Album (reference from another node) and scoped under each albumID there is a node (auto gen id) for each album entry (or picture). The expanded album has two album entries, the first of which is expanded.
In Firebase - I could fetch the set of album entries (for a given album) by doing the following
I could offset to the subnode and read from there.
let dbKey = "byAlbum_entries"
let ref = Database.database().reference(fromURL: firebaseDB_URL)
let albumEntryReference = ref.child( dbKey).child( forAlbum.objectid)
albumEntryReference.observeSingleEvent(of : .value, with : { (snapshot) in ...
In Firestore how do I retrieve that same set of album entries?
is the correct syntax similar to below? Can I get documents from a document and Firestore will know I am asking to look for a subcollection because I said getDocuments()?
let dbKey = "byAlbum_entries"
let ref = Firestore.firestore()
let albumEntryReference = ref.collection( dbKey).document( forAlbum.objectid)
albumEntryReference.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
// no album entries found
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
// loop through album entries
}
}
}
Part 2 --- Data Model Good Practices with FIRESTORE
It is better to restructure the data so that there is no subcollection and there is just a single collection where each entry includes both the albumID and the AlbumEntryID and I can just use a where clause to fetch only the album entries where albumID matches the one I am looking for? This would require an additional index whereas currently, in firebase, I can go directly to where I want to read and just read.
Even if restructuring does turn out to be better, I'd still appreciate help on the syntax to fetch all album entries for a given album as the database currently exists.

Resources