# #reactjs #firebase #google-cloud-firestore
Вопрос:
Я создаю веб-приложение, которое поможет людям создавать графики. Когда пользователь создает два графика и удаляет первый, индекс в массиве изменяется на 0, и поэтому второй график (график1) не удаляется из Firestore. Есть какие-нибудь идеи о том, как подойти к этому? Спасибо
Добавляет График
onClick={ () => {
const clientDb = firebaseClient.firestore();
// Adding Graph Options NOTICE HERE SITTING DOCUMENT NAME TO graph${i}
for(var i = 0 ; i < numberofGraphs.length ; i ){
clientDb.collection("Users").doc(props.uid).collection("Dashboard").doc(`graph${i}`).set({
type:numberofGraphs[i].type,
title:numberofGraphs[i].type,
seriestitle:numberofGraphs[i].seriestitle,
legend:numberofGraphs[i].legend,
xAxis:numberofGraphs[i].xAxis,
yAxis:numberofGraphs[i].yAxis,
color:numberofGraphs[i].color,
tooltipcolor:numberofGraphs[i].tooltipcolor,
tooltiptextcolor:numberofGraphs[i].tooltiptextcolor,
axisColor:numberofGraphs[i].axisColor,
})
}
}}
Удаляет График
numberofGraphs.map( (si, k) => (
<>
<CloseIcon
onClick={ () => {
if(window !== "undefined") {
console.log("lets see it")
const clientDb = firebaseClient.firestore();
//NOTICE HERE DELETING Graph with index from map
clientDb.collection("Users").doc(props.uid).collection("Dashboard").doc(`graph${k}`).delete();
}
const newgraphs = numberofGraphs.filter( (object, kk) => k!== kk )
setnumberofGraphs(newgraphs);
}}
/>
<CreateGraph2 type={si.type} title={si.title} seriestitle={si.seriestitle}/>
</>
))
Комментарии:
1. Просто предупреждение, которое вы там спрятали, вероятно, следует скопировать через заголовок.
title: numberofGraphs[i].type
2. Я рекомендую ознакомиться с рекомендациями: Массивы в Firebase , хотя в нем говорится о базе данных RTDB, его проблемы также применимы к Firestore и любой онлайн-базе данных. Лучший подход состоит в том, чтобы использовать автоматические идентификаторы документов для документов, а затем заказывать их на клиенте по времени создания, а не хранить их в базе данных по числовому индексу. Я бы также рекомендовал переместить все графики в их собственную
/Graphs
коллекцию или подколлекцию, а не включать их в/Dashboard
нее .
Ответ №1:
Если вам абсолютно необходимо сделать это таким образом, вы можете «пометить документ как удаленный», collection('Dashboard').doc('<doc-to-delete>').set({ deleted: true })
а затем просто отфильтровать его в клиенте по этому свойству и не отображать его.
В более общем плане — используйте collection().add()
для создания новых документов и позвольте firestore автоматически генерировать идентификаторы для вас. Затем получите доступ к своим документам по идентификатору, вместо того чтобы пытаться отслеживать индексы на переднем конце.
Комментарии:
1. Таким образом, в принципе, всякий раз, когда пользователь создает график, я должен напрямую добавлять его данные в коллекцию в firestore, а затем читать и сопоставлять с внешним интерфейсом непосредственно из базы данных ?
2. Нет, я ничего не говорил о сопоставлении значений базы данных с интерфейсом, напрямую или иным образом. Короче говоря, мой ответ был таким: не пытайтесь самостоятельно присваивать идентификаторы документам на основе их положения в массиве на интерфейсе. Позвольте Firestore автоматически генерировать идентификаторы для вас и использовать эти идентификаторы для работы с документами.
Ответ №2:
Я решил свою проблему, выполнив следующее:
Добавляет График
// Took @samthecodingman's advice by moving all graphs to their own /Graphs collection.
// Which also resonated with @Brian's answer to use
// collection().add() to add documents with Auto-generated ID's instead of adding graphs based
// on index no. of array.
onClick={ () => {
if(window !== "undefined") {
const clientDb = firebaseClient.firestore();
clientDb.collection("Users").doc(props.uid)
.collection("Dashboard")
.doc("First").collection("Graphs").add({
type:type, title:title, seriestitle:seriestitle,
legend:legend,
xAxis:xAxis,
yAxis:yAxis,
color:color,
tooltipcolor:tooltipcolor,
tooltiptextcolor:tooltiptextcolor,
axisColor:axisColor,
//passed an id filed to the object I'm saving
id:type title
})
}
}}
Удаляет График
//mapping through an array of objects (si) and then using the get() method with
a query to check for matching ID. Then used the id in the delete method
if(window !== "undefined") {
const clientDb = firebaseClient.firestore();
const docref = clientDb.collection("Users").doc(props.uid)
.collection("Dashboard").doc("First").collection("Graphs");
docref.where("id" , "==", `${si.type}${si.title}`)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
docref.doc(doc.id).delete()
console.log(doc.id, " => ", doc.data() );
});
})
}