Реакция: как использовать вызовы asyn c, чтобы получить FirebaseToken, а затем использовать его в вызове API? - PullRequest
1 голос
/ 18 июня 2020

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

componentDidMount() {

    let userId= this.context.userId;

    var url = "items/getAllMyItems/" + userId;
    Client.fetchData(url, data => {

      this.setState({items: data});

    });
}

Текущая настройка не имеет защиты (только для целей тестирования), и Клиент определяется следующим образом (это index. js):

function fetchData(fetchPath, cb) {
    return fetch(`https://api.url/${fetchPath}`, {accept: "application/json"})
    .then(cb);
}

(есть еще пара других функций которые проверяют результаты и c, но я оставил их для краткости).

Теперь мое приложение подключается к Firebase для обработки аутентификации. У меня есть компонент Firebase, который имеет 3 файла:

firebase. js:

import app from 'firebase/app';
import 'firebase/auth';

const config = {
  apiKey:  /* etc */,
};

class Firebase {
  constructor() {
    app.initializeApp(config);

    this.auth = app.auth();
  }

  // *** Auth API ***

  doSignInWithEmailAndPassword = (email, password) =>
    this.auth.signInWithEmailAndPassword(email, password);

  doSignOut = () => this.auth.signOut();

}

export default Firebase;

context. js:

import React from 'react';

const FirebaseContext = React.createContext(null);

export const withFirebase = Component => props => (
  <FirebaseContext.Consumer>
    {firebase => <Component {...props} firebase={firebase} />}
  </FirebaseContext.Consumer>
);

export default FirebaseContext;

index. js:

import FirebaseContext, { withFirebase } from './context';
import Firebase from './firebase';

export default Firebase;

export { FirebaseContext, withFirebase };

Сейчас мы реализуем внутреннюю безопасность, и мне нужно передать токен Firebase в API при выполнении вызовов. Я не могу понять, как это сделать правильно.

Я знаю, что мне нужно позвонить

firebase.auth().currentUser.getIdToken(true).then(function(idToken) {
  // API call with Authorization: Bearer `idToken`
}).catch(function(error) {
  // Handle error
});

, поэтому я решил, что Client / index. js нужно будет что-то изменить например:

import react from 'react';
import { FirebaseContext } from '../Firebase';

function fetchData(fetchPath, cb) {

  <FirebaseContext.Consumer>
    {firebase => {
      firebase.auth().currentUser.getIdToken(true)
      .then(function(idToken) {
        // API call with Authorization: Bearer `idToken`
        return fetch(`https://api.url/${fetchPath}`, {accept: "application/json"})
        .then(cb);
      }).catch(function(error) {
        // Handle error
      });
    }}
  </FirebaseContext.Consumer>

}

, но если я сделаю это, я получаю сообщение об ошибке «Ожидалось назначение или вызов функции, но вместо этого было видно выражение». Я понимаю, что это потому, что он ожидает, что я верну компонент, но я не хочу этого делать, потому что возвращать нечего. Я также попытался использовать useContext и изменить fetchData на:

const Client = () => {

  const firebase = useContext(FirebaseContext);

  firebase.auth().currentUser.getIdToken(true)
      .then(function(idToken) {
        // API call with Authorization: Bearer `idToken`
        fetch(`https://api.url/${fetchPath}`, {accept: "application/json"})
        .then(cb);
      }).catch(function(error) {
        // Handle error
  });

}

, но я получил сообщение об ошибке Invalid Hook Call.

Может ли кто-нибудь указать мне правильное направление?

1 Ответ

1 голос
/ 18 июня 2020

Код, который вы должны получить для идентификатора, мне нравится.

Как передать его в API, зависит от того, что этот API ожидает, но, поскольку вы упоминаете `` Авторизация: носитель idToken '', это обычно будет выглядеть так:

fetch(`https://api.url/${fetchPath}`, {
    headers: {
      'Accept': 'application/json',
      'Authorization': 'Bearer ' + idToken
    }
})
...