Удаление документа из Firestore на основе ключа массива

# #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() );
         });
     })
 
      }