Condición de carrera en Amplify.Hub signIn handler cuando se usa juramento

8

Código de ejemplo:

Hub.listen('auth', event => {
  const { event: type, data } = event.payload;

  if (type === 'signIn') {
    const session = data.signInUserSession;
    console.log('SESSION', data.signInUserSession);
    setTimeout(() => {
      console.log('SESSION', data.signInUserSession);
    }, 100);
  }
});

Al usar el juramento, después de que el proveedor redirige a mi aplicación, el Hub activa un signInevento. Sin embargo, la signInUserSessionpropiedad es nullcuando se dispara el evento, pero obtiene un valor algún tiempo después (dentro de 100 ms). Esto no parece ocurrir cuando se usa Auth.signIn(email, password)directamente; signInUserSessionse llena cuando se dispara el evento.

¿Qué está pasando aquí y cómo puedo solucionarlo? Actualmente, tengo un retraso explícito en el código, que es un hack terrible.

Thom Smith
fuente
¿Cuál es la versión que estás usando? Traté de reproducir esto en la aplicación que estoy usando sin éxito
karthick
Puede usar promesa en javascript también.
Prabhat
¿Dónde o cómo estás escuchando este evento, es el código parte de un componente o de una clase singleton?
karthick
Estoy usando redux-saga, y lo uso Hub.listenpara alimentar un canal de eventos. Sin embargo, también intenté ejecutar el código de ejemplo anterior directamente desde una saga, y tuve el mismo problema.
Thom Smith

Respuestas:

2

Quizás la antigua forma de JavaScript para esperar a que se complete el valor es útil para garantizar que el código no falle incluso si tarda más de lo esperado en completar el valor.

Aquí hay un código de muestra que normalmente uso cuando no hay otras opciones disponibles.

waitForValue(){
    if(myVar!= null && typeof myVar !== "undefined"){
        //value exists, do what you want
        console.log(myVar)
    }
    else{
        setTimeout(() => {this.waitForValue()}, 100);
    }
}

Puede refactorizar este código de muestra según su necesidad.

Alternativamente, AWS Amplify también tiene otras formas de obtener sesión iniciada por el usuario actual. Por ejemplo, Auth.currentAuthenticatedUser()y la Auth.currentSession()promesa de devolución. Se pueden usar así

private async getUser(){
    let user = null;
    try {
      user = await Auth.currentAuthenticatedUser();
      //console.log(user);
    } catch (err) {
      //console.log(err);
    }
    //return user;
  }
vsoni
fuente
0

no estoy acostumbrado a aws amplify, solo lea algunos github y hasta ahora puedo ver que necesitaremos información sobre su userPool implementación, supongo que hay algún problema extraño de devolución de llamada

Pero para una solución alternativa, puede proxy la referencia:

const event = {type: "signIn", data: {signInProperty: "null"}}

setTimeout(()=>event.data.signInProperty = "{Stack: Overflow}", 1000)

// mock events
function emit(type, args){
  console.log(type, args)
}

//initialize
let watchedValue = event.data.signInProperty
document.getElementById("app").innerHTML = event.data.signInProperty 
// protect reference
Object.defineProperty(event.data, "signInProperty", {
    set(newValue){
      watchedValue = newValue
      document.getElementById("app").innerHTML = newValue
      emit("event:signInCompleted", event.data)
    },
    get(){
      return watchedValue
    }
})
<div id="app"></div>

Estradiaz
fuente