I have an array of URLS stored within a document that i'd like to read and display as individual cards. All I'm getting is the return of the whole array, I'm not mapping it correctly and I don't know where I'm going wrong.
Currently, it's displaying "https://website1.com, https://website2.com". Where as I would like it to be individual items.
const getInternalLinks = async () => {
try {
const query = await db
.collection("internallinks")
.get()
.then((snapshot) => {
const tempData = [];
snapshot.forEach((doc) => {
const data = doc.data();
tempData.push(data);
});
setInternalLinks(tempData);
});
} catch (err) {
console.error(err);
};
};
useEffect(() => {
getInternalLinks()
},[])
return (
{internalLinks.map((doc, index) => {
<Card>
<p>{doc.urls.urls}</p>
</Card>
}))
);
Firebase Collection Structure
Try adding it directly to the state:
const [internalLinks, setInternalLinks] = useState([]);
const getInternalLinks = async () => {
try {
const query = await db
.collection("internallinks")
.get()
.then((snapshot) => {
snapshot.forEach((doc) => {
const data = doc.data();
setInternalLinks([ ...internalLinks, data ]);
});
});
} catch (err) {
console.error(err);
};
};
Related
I am currently working with a clone of a streaming platform, it turns out that this clone has the TMDB API integrated and I want to remove it to store the objects returned by this api in a firebase database, but I am a little confused.
In my Firebase file, I have a promise that returns an array of objects and it looks like this:
export const getGamesDocument = () => {
return new Promise((resolve, reject) => {
const documents = [];
firestore
.collection("games")
.get()
.then((snapshot) => {
snapshot.forEach((doc) => {
const documentData = doc.data();
documentData.id = doc.id;
documents.push(documentData);
});
resolve(documents);
})
.catch((error) => {
reject(error);
});
});
};
So far everything is going well where I am getting confused is in this redux code since I have no knowledge of the subject:
export const fetchAdventureMoviesRequest = () => ({
type: moviesActionTypes.FETCH_ADVENTURE_MOVIES_REQUEST,
});
export const fetchAdventureMoviesSuccess = (adventureMovies, isPage) => ({
type: isPage
? moviesActionTypes.FETCH_ADVENTURE_MOVIES_SUCCESS
: moviesActionTypes.LOAD_MORE_ADVENTURE_MOVIES_SUCCESS,
payload: adventureMovies,
});
export const fetchAdventureMoviesFailure = error => ({
type: moviesActionTypes.FETCH_ADVENTURE_MOVIES_FAILURE,
payload: error,
});
export const fetchAdventureMoviesAsync = (fetchUrl, isPage) => {
return dispatch => {
dispatch(fetchAdventureMoviesRequest());
axios
.get(fetchUrl)
.then(res => {
const adventureMovies = res.data.results.map(el => ({
...el,
isFavourite: false,
}));
if (isPage) {
dispatch(fetchAdventureMoviesSuccess(adventureMovies, isPage));
} else dispatch(fetchAdventureMoviesSuccess(adventureMovies));
})
.catch(error => {
const errorMessage = error.message;
dispatch(fetchAdventureMoviesFailure(errorMessage));
});
};
};
I want to remove the array of objects that are obtained in the constant "adventureMovies" and replace it with the array of objects that I obtain in the aforementioned promise.
Im tryng to display firestore data but I just get one value. I have try forEach and map. Nothing is working. Heres my code:
React.useEffect(() => {
retrieveNetwork();
}, []);
const retrieveNetwork = async () => {
try {
const q = query(collection(db, "cities", uidx, "adress"));
const querySnapshot = await getDocs(q);
let result = [];
//querySnapshot.docs.map((doc) => setGas(doc.data().home));
querySnapshot.docs.map((doc) => {
result.push(doc.data().home);
setGas(result);
});
} catch (e) {
alert(e);
}
};```
The .map method returns an array (official docs here), so you could do something like this:
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
React.useEffect(() => {
retrieveNetwork();
}, []);
const retrieveNetwork = async () => {
try {
const q = query(collection(db, "cities", uidx, "adress"));
const querySnapshot = await getDocs(q);
// an array from the docs filled only with "home" data
const results = querySnapshot.docs.map((doc) => {
return doc.data().home;
});
// only update the state once per invokation
setGas(results)
} catch (e) {
alert(e);
}
};
I have created a function where i have passed an object as an argument and there are multiple objects which is passed on one by one and the output is an object but it comes as an individual object which is fine because I have written the code in that way now i wanted to store the objects into an array so it becomes an array of objects.and store for all objects
here is the tried code which gives single object example
const {db} = require('./constant')
const momentTz = require("moment-timezone");
const { getAuth } = require("./constant");
const officeStatus = async officeActivity => {
let output = {};
const maileventQuerySnapshot = await db
.collection("MailEvents")
.where("office", "==", officeActivity.office)
.where("event", "==", "delivered")
.limit(1).get();
output["office"] = officeActivity.office;
output["First Contact"] = officeActivity.attachment["First Contact"].value;
output["Second Contact"] = officeActivity.attachment["Second Contact"].value;
output["Office Creation Date"] = momentTz
.tz(officeActivity.timestamp, officeActivity.attachment.Timezone.value)
.format("DD MMM YYYY");
output["Reports Sent"] = maileventQuerySnapshot.docs.length ? true:false
const officeSubcollectionSnapshot = await db
.collection(`Offices/${officeActivity.officeId}/Addendum`)
.where("date","==",parseInt( momentTz(new Date()).subtract(1, "days").format("DD")))
.where('month', '==', parseInt( momentTz(new Date()).subtract(1, 'days').format("MM"))-1)
.where('year', '==',parseInt( momentTz(new Date()).subtract(1, "days").format("YYYY")))
.orderBy("user").orderBy('timestamp')
.get();
output['Number of unique Checkin Yesterday'] =
officeSubcollectionSnapshot.docs.length;
const activitiesRefSnapshot = await db
.collection("Activities")
.where("office", "==", officeActivity.office)
.where("template", "==", "subscription")
.where("attachment.Template.value", "==", "check-in")
.get();
const phoneNumberArray = [];
activitiesRefSnapshot.forEach(doc => {
phoneNumberArray.push(doc.data().attachment["Phone Number"].value);
});
const userRecord = await Promise.all(phoneNumberArray.map(getAuth));
output["Number of checkin Subscription Auth"] = userRecord.filter(
doc => doc !== undefined
).length;
output["Number of Checkin Subscription No Auth"] = userRecord.filter(
doc => doc === undefined
).length;
return { output};
};
module.exports = { officeStatus };
and the other file where i have queried the office and passed objects as an argument
const {admin,db} = require('./constant');
const { officeStatus } = require("./officeStatus");
let execute = async () => {
try {
let office = await db.collection("Offices").where("status", "==", "PENDING").get();
office.forEach(doc => {
officeStatus(doc.data())
.then(e => {
console.log(JSON.stringify(e.output));
})
.catch(error => {
console.log(error);
});
});
return;
} catch (error) {
console.log(error);
}
return;
};
execute();
admin.apps[0].delete();
I have get output in this way
{}
{}
{}....
and I wanted the output in this way
[{},{},{}]
The promise inside forEach is not correct. It wouldn't give you expected results. You shouldn't use that as it is not supported. You should consider using for..of or Promise.all. In your case I would suggest to use Promise.all as you need result in array.
Promise.all(office.docs.map(doc => {
return officeStatus(doc.data())
.then(e => {
return e.output;
})
.catch(error => {
console.log(error);
});
}))
.then(res => console.log(res));
Try doing that :
// and the other file where i have queried the office and passed objects as an argument
const {admin,db} = require('./constant');
const { officeStatus } = require("./officeStatus");
let execute = async () => {
try {
let office = await db.collection("Offices").where("status", "==", "PENDING").get();
let arr = new Array();
office.forEach(doc => {
officeStatus(doc.data())
.then(e => {
arr.push(e)
})
.catch(error => {
console.log(error);
});
});
console.log(arr)
return;
} catch (error) {
console.log(error);
}
return;
};
execute();
admin.apps[0].delete();
I just created an array where we push e when we did officeStatus. Then, at the end of the code, we log arr ; the declared array.
const {admin,db} = require('./constant');
const { officeStatus } = require("./officeStatus");
let execute = async () => {
let office = await db.collection("Offices").where("status", "==", "PENDING").get()
const arrayofObject = await Promise.all(office.docs.map(doc => {
return officeStatus(doc.data())
.then(e => {
// console.log(JSON.stringify(e.output));
return e.output;
})
.catch(error => {
console.log(error);
});
}))
console.log(arrayofObject)
return;
};
execute();
admin.apps[0].delete();
Hi i'm new to cloud functions, i was trying to update name in the collection when there is a Chang(update) on family document, but i cannot update name in the collection, seems like line is not executing after first console log.
exports.onClassroomUpdate = functions.firestore.document("family/{id}").onUpdate((change, context) => {
const documentId = context.params.id;
const after = change.after.data();
let users = admin.firestore().collection('users').where('family.id', '==', documentId);
return users.get().then((querySnapshot) => {
let chain = Promise.resolve();
console.log('work');
querySnapshot.forEach((doc) => {
console.log('not working');
chain = chain.then(() => {
return admin.firestore().collection('users').doc(doc.id).update({
name: after.name
});
});
});
return Promise.all([chain]);
})
}).catch(err => {
console.log(err);
return Promise.reject(err);
});
)}
db.collection("City").get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
db.collection("users").where("City", "==", doc.id).get().then(function(querySnapshot) {
var jgy_usercount = querySnapshot.size;
retArr.push(jgy_usercount);
});
});
});
The retArr has the number of users per city that is stored in the array. this array i need to use elsewhere out of the function. How can retrieve it?
You could do something like this:
async function getUsersPerDistrict() {
const querySnapshot = await db.collection("district").get()
const districts = []
querySnapshot.forEach(x => { districts.push(x.data) })
const districtCounts = await Promise.all(
districts.map(async x => {
const usersFromDistrict = await db.collection("users").where("City", "==", x.id).get()
return { count: usersFromDistrict.size, name: x.name }
})
)
return districtCounts
}
Without async/await:
function getUsersPerDistrict() {
return db.collection("district").get().then(querySnapshot => {
const districts = []
querySnapshot.forEach(x => { districts.push(x.data) })
const districtCounts = Promise.all(
districts.map(x =>
db.collection("users").where("City", "==", x.id).get()
.then(usersFromDistrict => ({
count: usersFromDistrict.size,
name: x.name
}))
)
)
return districtCounts
}