Не удается использовать возвращенное электронное письмо и токен из AsyncStorage / SecureStore в React Native?

#javascript #react-native #callback #expo #asyncstorage

#javascript #react-native #обратный вызов #выставка #asyncstorage

Вопрос:

Я искал ответ на свою проблему, но, похоже, не могу найти ничего подобного. Мой код возвращает значение, как и ожидалось!

Я создаю приложение в React-Native и в настоящее время работаю над входом в систему. Мне нужно сохранить идентификатор пользователя, userEmail и UserToken, и я выбрал AsyncStorage и SecureStore Expo в качестве опций, но у меня действительно странная проблема, которую я никогда раньше не видел.

Я могу установить и прочитать требуемые данные, но когда я пытаюсь их использовать, это просто не работает, но когда я жестко их кодирую, это работает? (это немного сложно объяснить).

В этом и заключается проблема. Для удобства чтения я опустил остальную часть кода, он отлично работает, если я жестко закодирую приведенные ниже значения…

     // Set the email and token
    // Before setting these, I logged the key's values and (of course), they were null
    // After setting them I logged them out again and they're set

/** from promise (no problems) **/

    SecureStore.setItemAsync('shifterEmail', responseJson.email);
    SecureStore.setItemAsync('shifterToken', responseJson.token);

/** returns response (no problems) **/
  

…тем временем, далее по странице…

 /** another function **/
    let shifterEmail = '';
    let shifterToken = '';

    SecureStore.getItemAsync('shifterEmail')
        .then((email) => {
            shifterEmail = email;
            console.log('API email: ', shifterEmail); // my@email.com <- good!
        })
        .catch((error) => {
            console.log('API email error: ', error);
        });

    SecureStore.getItemAsync('shifterToken')
        .then((token) => {
            shifterToken = token;
            console.log('API token: ', shifterToken); // random token <- good!
        })
        .catch((error) => {
            console.log('API token error: ', error);
        });

    return {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': 'Token'  
        ' token='   shifterToken   // WHAAAT <- doesn't work
        ', email='   shifterEmail, // WHAAAT <- doesn't work
    };
  

У меня была мозговая волна, и, хотя это могла быть старая добрая асинхронность, я попытался вложить их в свои обратные вызовы, но это не имеет значения.
Я показал код для SecureStore здесь, но то же самое с AsyncStorage , я могу получить ожидаемые значения для электронного письма и токена, но это просто не работает.

Но вот странный момент, который я не понимаю…

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

разум = взорван

  • Я могу использовать typeof , чтобы убедиться, что это строка.
  • Я пробовал JSON.stringify() и JSON.parse() установить и получить.
  • Я попытался настроить и получить его в строке, а также в качестве вызываемых функций.
  • Я попытался вложить обратные вызовы и оставить их последовательными.
  • Я даже попытался добавить тайм-аут к возврату, чтобы убедиться, что все установлено.

… ничего не работает 🙁

На заметку: это обе строки, но у меня была такая же проблема с числом, и единственный способ заставить это работать — вывести ‘get’ (как из AsyncStorage, так и из SecureStore) из их вызываемых функций и вставить код в строку. Кроме того, если вместо сохранения электронного письма и токена я просто добавлю его в переменную и использую это в возврате, это работает просто отлично, но это бесполезно, поскольку пользователю придется входить в систему каждый раз, когда они открывают приложение.

Совершенно сбит с толку. Рад ответить на любые вопросы, я перепробовал множество, так что мы можем пообщаться в старом добром чате, или, если вы можете предложить другой способ входа в систему, я бы тоже хотел это услышать!

Почему я не могу использовать значение, когда оно ПРЯМО ТАМ, но могу жестко закодировать то же самое???

Спасибо!

Ответ №1:

Похоже, что это проблема с асинхронностью. На основе предоставленного вами фрагмента кода оператор return может выполняться до .then обратного вызова.

Простым решением может быть использование async/await или Promise.all

Например:

Асинхронный / ожидающий

 const getToken = async () => {
    try{
      const email = await SecureStore.getItemAsync('shifterEmail')
      const token = await SecureStore.getItemAsync('shifterToken')

      return {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': 'Token'  
        ' token='   token   
        ', email='   email
      };
    } catch(error) {
      console.error(error);
      throw error;
    }
 }
  

Promise.all

 
 const getToken = () => {
    Promise.all([
      SecureStore.getItemAsync('shifterEmail'),
      SecureStore.getItemAsync('shifterToken')  
    ])
   .then((response) => {
      const [email, token] = response
       return {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
          'Authorization': 'Token'  
          ' token='   token   
          ', email='   email
        };
      }
    ).catch((error) => {
      console.error(error);
      throw error;
    });
 }
  

Комментарии:

1. Спасибо за ответ, но он все тот же. Я могу выйти из системы с электронной почтой и токеном, но он не принимает их при возврате… и они выглядели такими многообещающими! (бдум тш… <- понял?! Ha!). В конце этого я попытался обернуть блок возврата в оператор IF (например, IF(email === 'my@Email.com) ), чтобы он должен был соответствовать, прежде чем продолжить, что они и делают, но он по-прежнему не принимает электронное письмо и токен:(

Ответ №2:

Приведенный выше код выполняется асинхронно, и, как таковой, приведенный ниже код в инструкции return еще не был установлен.

Вы не опубликовали всю функцию, но оператор return, вероятно, здесь не сработает, и вам нужно будет передать функцию обратного вызова.

 const doSomethingWithLogin = headers =>
  console.log(headers)
  
Promise.all([
  SecureStore.getItemAsync('shifterEmail'),
  SecureStore.getItemAsync('shifterToken')  
])
  .then(([shifterEmail, shifterToken]) =>
    Promise.resolve({
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'Authorization': 'Token'  
      ' token='   shifterToken   
      ', email='   shifterEmail,
    })
  )
  .then(doSomethingWithLogin)  

Комментарии:

1. Спасибо за ответ, но он все тот же. Я могу вывести электронное письмо и токен, но они не работают, когда я их использую:(

Ответ №3:

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

после получения токена из хранилища при выполнении чего-то вроде:

'token=' token что на самом деле получается: token="sadfaswerw" Другими словами, токен по какой-то причине заключен в кавычки. Достаточно просто заменить кавычки, но немного странно.

Комментарии:

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

2. Я вернулся к этому и понял, что проблема с моей стороны заключалась в том, что я сохранял токен как json.