Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre habitué
    [React/Redux/Firestore] Parcourir des collections stockées en arbre (tree)
    Bonjour à tous,
    J'essaie depuis plusieurs jours de parcourir ma BDD (Firestore) afin de rendre les éléments dans un Tree.
    La parcours récursif dans Firestore fonctionne bien, cependant je n'arrive pas à stocker mon objet dans Redux une fois qu'il est fini d'être chargé.
    Je comprends pourquoi mon rendu ne donne que le 1er niveau et pourquoi le length affiche 0 alors qu'il y a bien des objets dans la liste (lié au fait que les fonctions sont asynchrones et que la console affiche les objets en référence), mais je n'arrive pas à trouver la solution pour mettre l'objet complet c'est à dire avec toutes les sous collections dans mon store au bon moment.

    Si quelqu'un à une idée, je suis preneur.
    Merci


    Un exemple de code parlera plus :
    Un objet "play" est une feuille de l'arbre et un objet "category" est un nœud.

    Ma base de données Firestore:


    Collection users:


    Sous collection plays (type = category)


    Sous collection plays (type = play)



    Fonctions de scrutation:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
      componentDidMount(){
        // Mise à jour de l'authentification
        this.authListener();
      }
     
      authListener = () => {
        firebase.auth().onAuthStateChanged((user) => {
          if(user){ // Si l'utilisateur est connecté
            firebase.firestore().collection("users").doc(user.uid).get().then(snapshot => {
              this.props.setUser(snapshot.data())
            })
            firebase.firestore().collection(`users/${user.uid}/plays`).onSnapshot(snapshot => {  // Si l'utilisateur est connecté parcours du 1er noeud de la collection
              let plays = []
              snapshot.forEach(doc => { 
                if(doc.data().type === "play"){ // Si l'objet est "play" alors c'est une feuille de l'arbre
                  plays.push(doc.data())
                }else if(doc.data().type === "category"){ // Si l'objet est "category" alors c'est un noeud de l'arbre
                  const cat = doc.data();
                  cat.plays = []
                  this.getAllPlaysForUser(cat.plays, `users/${user.uid}/plays/${doc.id}/plays`); // Récursivité avec en paramètre l'objet à mettre à jour et le path de la prochaine sous collection
                  plays.push(cat) // ajout du noeud au parent
                }
              })
              console.log("plays", plays);
              console.log("plays.length", plays.length);
              this.props.setPlays(plays) // mise à jour du store mais n'est pas complet car les appels sont asynchrone
            })
          }else{
            this.props.setPlays([]) // Vide le store si l'utilisateur n'est pas connecté
          }
        })
      }
     
      getAllPlaysForUser = (plays, path) => {
        firebase.firestore().collection(path).onSnapshot(snapshot => { // Parcours des noeuds suivant
          snapshot.forEach(doc => {
            if(doc.data().type === "play"){ // Si l'objet est "play" alors c'est une feuille de l'arbre
              plays.push(doc.data())
            }else if(doc.data().type === "category"){ // Si l'objet est "category" alors c'est un noeud de l'arbre
              const cat = doc.data();
              cat.plays = []
              this.getAllPlaysForUser(cat.plays, `${path}/${doc.id}/plays`);// Récursivité avec en paramètre l'objet à mettre à jour et le path de la prochaine sous collection
              plays.push(cat) // ajout du noeud au parent
            }
          })
        })
      }


    Le résultat mais seulement du 1er niveau


    Mon log console lors du parcours de l'objet mis dans le store pour la construction de l'arbre:

  2. #2
    Membre régulier
    Bonjour,

    Je ne sais pas si ton pb vient de la, juste une idee qui me passe par la tete: avec redux on doit cloner toutes les couches, les embedded arrays et objects.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
     
    const paxInfo = {
       name: "paul",
       age: 23,
       adresse: {
          rue: "de la soif",
          numero: 12,
          contact: {
             tel: 54765475,
             email: "jgfj@khjgk.com"
          }
       }
    }
     
    // dans le reducer de redux
    const sendContact = (state, action) => {
       return {
          ...state,
              paxInfo: {
                 ...state.paxInfo,
                    adresse: {
                       ...state.paxInfo.adresse,
                          contact: {
                             ...state.paxInfo.adresse.contact
                         }
                      }
                }
         }
    }


    vois ce lien https://redux.js.org/recipes/structu...pdate-patterns

  3. #3
    Membre habitué
    Salut,
    Merci pour ta réponse.
    Du coup j'ai géré autrement et mis en state local de chaque noeud la liste de ses fils. J'avais pas vraiment d'intérêt à les mettre dans un store.

    Et pour simplifier les appels firestore, j'ai chargé le 1er niveau puis chaque niveau suivant sera chargé dynamiquement à la première ouverture du noeud.

    Merci de ton aide en tout cas.

###raw>template_hook.ano_emploi###