0

Je développe actuellement ma première grande application web avec ReactJS en utilisant Firebase comme base de données. Tout allait bien jusqu'à ce que je suis tombé sur ce problème.Firebase's set() ne fonctionne pas à l'intérieur onAuthStateChanged()

J'essaie d'enregistrer les informations de l'utilisateur lorsqu'ils se connectent à l'application avec Facebook ou Twitter, j'utilise les méthodes fournies par Firebase comme ceci:

authenticate(option){   

    let provider; 

    switch (option) { 
     case 'facebook': 
      provider = new firebase.auth.FacebookAuthProvider();     
      break; 
     case 'twitter': 
      provider = new firebase.auth.TwitterAuthProvider(); 
      break; 
     default: 
      provider = 'no-provider' 
      break; 
    } 

    if(provider !== 'no-provider'){ 
     firebase.auth().signInWithPopup(provider).then((result) => { 
      console.log("Login with " + provider + " ok!"); 
      console.log(result); 
     }).catch((error) => { 
      console.log("Error: there was an error trying to login."); 
     }); 
    } 
} 

Mais lorsque je tente de sauver l'utilisateur dans la base de données une fois qu'ils se sont connectés, rien ne se passe.

C'est ce que j'ai sur app.js

componentDidMount() { 
    base.auth().onAuthStateChanged((loggedUser) => { 
     if (loggedUser) { 
      this.setState({ 
       userName: loggedUser.displayName, 
       userPhoto: loggedUser.photoURL, 
       userUID: loggedUser.uid 
      }); 

      base.database().ref('users/' + loggedUser.uid).on('value', 
       (user) => { 
        if (user.val() !== null) { 
         if (user.val().votedAlbums !== undefined) { 
          this.setState({ 
           votedAlbums: user.val().votedAlbums 
          }); 
         } 
        } else { 
         console.log(loggedUser.uid); 
         let userInfo = { 
          lastActivityTime: new Date() 
         } 
         base.database().ref('users/' + loggedUser.uid).set(userInfo).then((ref) =>{ 
          console.log(ref); // this logs 'undefined' 
         }).catch((error) => { 
          console.log(error); 
         }); 
        } 
       }, 
       (err) => { 
        this.props.history.push('/error'); 
       } 
      ); 


     } 
    }); 
} 

j'ai essayé sauver l'utilisateur sur une autre fonction et il fonctionne aussi bien update() et set(). Mais quand j'appelle set() à l'intérieur de onAuthStateChanged() ce n'est pas le cas.

Mes règles sont DB:

{ 
    "rules": { 
    ".read": true, 
    ".write": "auth != null" 
    } 
} 

Suis-je manque quelque chose?

Merci

+0

Pouvez-vous confirmer que 'loggedUser.uid' n'est pas vide avant la méthode set avec' console.log (loggedUser.uid) ' – bennygenel

+0

@bennygenel Oui, n'est pas vide. J'ai seulement testé avec un utilisateur. J'ai fait un 'console.log (loggedUser);' et l'uid était là. –

+0

Où vous êtes-vous connecté? à l'intérieur du rappel de 'on ('value', ....)'? – bennygenel

Répondre

0

Comme @bennygenel le suggérez, j'ai changé la valeur de lastActivityTime à une chaîne simple comme ceci:

componentDidMount() { 
     base.auth().onAuthStateChanged((loggedUser) => { 
      if (loggedUser) { 
       this.setState({ 
        userName: loggedUser.displayName, 
        userPhoto: loggedUser.photoURL, 
        userUID: loggedUser.uid 
       }); 

       base.database().ref('users/' + loggedUser.uid).once('value', 
        (user) => { 
         if (user.val() !== null) { 
          if (user.val().votedAlbums !== undefined) { 
           this.setState({ 
            votedAlbums: user.val().votedAlbums 
           }); 
          } 
         } else { 
          console.log(loggedUser.uid); 

          let userInfo = { 
           lastActivityTime: "whatever" // replaced new Date() with "whatever" 
          } 
          base.database().ref('users/' + loggedUser.uid).set(userInfo).then((ref) =>{ 
           console.log(ref); 
          }).catch((error) => { 
           console.log(error); 
          }); 
         } 
        }, 
        (err) => { 
         this.props.history.push('/error'); 
        } 
       ); 


      } 
     }); 
    } 

Et maintenant, lorsque l'utilisateur se connecte à son ajouté à la DB. J'ai également changé la méthode on() avec once() car il ajoutait l'utilisateur même si je supprimais directement de la console Firebase.

Maintenant, pour ajouter la date à lastActivityItem je dois seulement ajouter la méthode toString() à la date générée comme ceci:

let d = new Date() 

let userInfo = { 
    lastActivityTime: d.toString() 
} 

Si quelqu'un sait pourquoi cela est arrivé, s'il vous plaît partager.

Merci @bennygenel !!!

+0

Parce que 'new Date' est un objet date et vous avez besoin de le mettre en forme de chaîne. Vous pouvez utiliser une méthode toString ou une méthode getTime – bennygenel