Информация между несколькими данными в React Firebase - PullRequest
0 голосов
/ 29 августа 2018

У меня есть приложение React с зоной администрирования, где пользователь с правами администратора может добавлять некоторые элементы в большой каталог. Данные сохраняются в Firebase в «каталоге».

Когда простой пользователь приложения подключается к своей учетной записи, он может просмотреть список элементов, добавленных администратором, и выбрать добавить элемент в свою коллекцию (например, добавить в любимую функцию). Ее коллекция затем отображается на частной странице "Коллекция пользователей".

Моя проблема заключается в том, что когда администратор удаляет элемент в зоне администратора, этот элемент также удаляется в каталог, но не в пользовательскую коллекцию.

Вы можете увидеть мой код здесь:

Данные из Firebase на «страницу каталога»:

class Catalogue extends React.Component {
  constructor(){
  super();
  this.state = {
   catalogue: {}
  };
}

//Item from  Firebase
  componentDidMount() {
  database.on('value', snapshot => {
  this.setState({
     catalogue: snapshot.val()
    });
   });
  }

// Add item to user collection
  addToCollection(key, e) {
  const userUid = firebase.auth().currentUser.uid;
  const collection = {
    marque: this.state.catalogue[key].marque,
    marquesuite: this.state.catalogue[key].marquesuite,
    numero: this.state.catalogue[key].numero,
    reference: this.state.catalogue[key].reference,
    cote: this.state.catalogue[key].cote,
    avatarURL:this.state.catalogue[key].avatarURL
  };
  firebase.database().ref(`users/${userUid}/collection`).child('items').ref.push(collection);

 }




 render(){

if(this.state.catalogue === null) {
  return  <p>Catalogue is empty</p>

}


const catalogue= Object.keys(this.state.catalogue).map(key => {
  return (

    <div className="item col-md-2" key={key}>
      <img src={this.state.catalogue[key].avatarURL} height={150} with={150}/>
      <h3>{this.state.catalogue[key].marque}</h3>
      <h3>{this.state.catalogue[key].marquesuite}</h3>
      <h4>{this.state.catalogue[key].numero}</h4>
      <h4>{this.state.catalogue[key].reference}</h4>
      <p>{this.state.catalogue[key].cote}</p>
      <div className="text-center">
      <button className="btn btn-success" onClick={this.addToCollection.bind(this, key)}>Add to my collection</button>
      </div>
    </div>

      )
    });
  return (
    <div class="container-fluid">
      <h1 class="text-center">List of item</h1>
      {catalogue}
    </div>
    )
   }
  }

  const authCondition = (authUser) => !!authUser;

  export default withAuthorization(authCondition)(Catalogue);

Это моя «Страница коллекции пользователей»:

   class Collection extends React.Component {
   constructor (props) {
   super(props)
   this.state = {
    collection: {}
   };

   }

   //Data from Firebase Database
   componentDidMount() {
   var userUid = firebase.auth().currentUser.uid;
   const collection =firebase.database().ref(`/users/${userUid}/collection/items`).orderByChild('marque')

   collection.on('value', snapshot => {
   this.setState({
   collection: snapshot.val(),
  })
 })
}

//Remove from user collection
  removeToCollection(key, e) {
  const userUid = firebase.auth().currentUser.uid;
  const item = key;
  firebase.database().ref(`users/${userUid}/collection/items/${item}`)
  .remove();
}

  renderPosts() {
  this.removeToCollection = this.removeToCollection.bind(this);
  return _.map(this.state.collection, (collection, key) => {
  return (
    <div className="item col-md-3" key={key} id={key}>
       <img src={this.state.collection[key].avatarURL} height={150} with={150}/>
     <h3>{collection.marque}</h3>
     <h3>{collection.marquesuite}</h3>
     <h4>{collection.numero}</h4>
     <h4>{collection.reference}</h4>
     <p>{collection.cote}</p>
     <div className="text-center">
     <button className="btn btn-danger" onClick={(e) => {if(window.confirm('Are you sure ?')){this.removeToCollection(key, e)};}}>Remove from my collection</button>
     </div>

 </div>
 )
})
}

render(){
  if(this.state.collection === null){
  return <h2>Your collection is empty</h2>
 }
  return (
    <div class="container-fluid">
    <h1 class="text-center">Your collection</h1>
    {this.renderPosts()}
  </div>
)
}

}

const authCondition = (authUser) => !!authUser;

export default withAuthorization(authCondition)(Collection);

Есть идеи?

Спасибо за вашу помощь

1 Ответ

0 голосов
/ 29 августа 2018

База данных Firebase Realtime не имеет ссылок между свойствами. Это означает, что, хотя вы, как разработчик или пользователь, можете видеть, что каждый элемент в коллекции должен соответствовать элементу в каталоге, Firebase не имеет встроенного способа обеспечить это отношение.

Что вы можете сделать, это добавить правила проверки, обеспечивающие существование элементов в пользовательской коллекции. Скажем, например, что вы храните каталог и пользовательские коллекции следующим образом:

catalogue: {
  item1: { name: "Cookies" },
  item2: { name: "Cookies" },
  item3: { name: "Cookies" }
},
collections: {
  user1: {
    item1: true,
    item2: true
  },
  user2: {
    item2: true,
    item3: true
  }
}

Вы можете использовать следующие правила безопасности, чтобы гарантировать, что каждый /collections/$uid/$itemId также должен существовать в /catalogue:

{
  "rules": {
    "collections": {
      "$uid": {
        "$itemId": {
          ".validate": "root.child('catalogue').child($itemId).exists()"
        }
      }
    }
  }
}

Это означает, что вы можете удалить элемент из каталога, только если в пользовательских коллекциях больше нет ссылок на этот элемент. Таким образом, для приведенных выше примеров данных эта запись завершится неудачно (поскольку два пользователя имеют элемент в своей коллекции):

firebase.database().ref("catalogue").child("item2").remove()

Но если мы последовательно запустим следующий код, он будет работать:

firebase.database().ref("collections/user1/item2").remove().then(function() {
  firebase.database().ref("collections/user2/item2").remove().then(function() {
    firebase.database().ref("catalogue").child("item2").remove()
  })
})

Это вложение кода довольно неудобно, и обновления не являются атомарными. Вот почему вы часто будете видеть такие «каскадные удаления», выполняемые с помощью одного обновления нескольких местоположений:

firebase.database().ref().update({
  "collections/user1/item2": null,
  "collections/user2/item2": null,
  "catalogue/item2": null
})

Этот единственный оператор обновляет три свойства в базе данных и подтверждает, что результат всех трех обновлений в сочетании действителен в соответствии с правилами (что в данном случае и так).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...