Reputation: 127
This is my situation: I have a local json file with a lot of entries. This file is not sanitized (i.e. there might be repeated entries in the list). My goal is to add each item (once) from the local file to my DB using firestore.
The docs say that a transaction can be multiple get
operations followed by multiple update/set/delete
operations.However, the samples usually only have a single get
. How can I go and have multiple get operations without nesting inside then()
? I guess I could get the entire collection and compare the result. But then I won't have learned how to use multiple get
!
Sample data:
/* mock data */
var myList = [
{
id: '123',
name: 'Aloha 1',
latitude: 0.0,
longitude: 1.1,
url: 'https://www.google.com'
},
{
id: '321',
name: 'Aloha 2',
latitude: 3.0,
longitude: 3.1,
url: 'https://www.gmail.com'
},
{
id: '123',
name: 'Aloha 1',
latitude: 0.0,
longitude: 1.1,
url: 'https://www.google.com'
},
{
id: '321',
name: 'Aloha 2',
latitude: 3.0,
longitude: 3.1,
url: 'https://www.gmail.com'
}
];
This is my attempt (I know this is wrong, I have a sequence of get
/set
operations...):
var transaction = db.runTransaction(t => {
for (item in myList) {
const ref = db.collection('superList').doc(item.id);
const sanitizedEntry = {
name: item.name,
location: new admin.firestore.GeoPoint(item.lat, item.lon),
url: item.url,
}
t.get(ref).then(doc => {
if (!doc.exists) {
t.set(ref, sanitizedEntry);
}
});
}
})
.then(result => {
console.log('Transaction success!');
})
.catch(err => {
console.log('Transaction failure:', err);
});
The resulting DB should only contain superList/123
, and superList/321
(plus whatever other documents are already in the collection).
Upvotes: 0
Views: 765
Reputation: 4908
If you have a fixed number of items to check, you can use getAll to get many documents concurrently. This is an all or nothing result. You'll either get all documents or an error.
let superList = db.collection('superList');
let myRef0 = superList.doc(item[0].id);
let myRef1 = superList.doc(item[1].id);
let myRef2 = superList.doc(item[2].id);
let myRef3 = superList.doc(item[3].id);
return db.getAll(itemRef0, itemRef1, itemRef2, itemRef3).then(response => {
// The data is returned in an array, here
}.catch(err => {
console.error(`An error happened ${err}`);
});
Upvotes: 1
Reputation: 127
As per suggestion, not using transactions worked fine (edit: fixed code):
for (item in myList) {
const itemRef = db.collection('superList').doc(item.id);
const itemDoc = itemRef.get()
.then(itemSnap => {
if (!itemSnap.exists) {
const itemObj = {
name: gymitemRaw.name,
location: new admin.firestore.GeoPoint(item.llatitude, item.longitude),
url: item.url,
};
itemRef.set(itemObj);
}else{
console.log('Item already exists in DB');
}
});
}
Upvotes: 0