Когда и где проверять пользователя Firebase в React - PullRequest
0 голосов
/ 22 января 2020

Я пытаюсь выяснить, как использовать Firebase.

У меня есть конфигурация с аутентификатором auth:

 onAuthUserListener(next, fallback) {
    // onUserDataListener(next, fallback) {
      return this.auth.onAuthStateChanged(authUser => {
        if (!authUser) {
          // user not logged in, call fallback handler
          fallback();
          return;
        }

        this.user(authUser.uid).get()
          .then(snapshot => {
            let snapshotData = snapshot.data();

            let userData = {
              ...snapshotData, // snapshotData first so it doesn't override information from authUser object
              uid: authUser.uid,
              email: authUser.email,
              emailVerified: authUser.emailVerifed,
              providerData: authUser.providerData
            };

            setTimeout(() => next(userData), 0); // escapes this Promise's error handler
          })
          .catch(err => {
            // TODO: Handle error?
            console.error('An error occured -> ', err.code ? err.code + ': ' + err.message : (err.message || err));
            setTimeout(fallback, 0); // escapes this Promise's error handler
          });
      });
    }

    // ... other methods ...
  // }  

Я прочитал документацию о создании слушателя, чтобы увидеть, есть authUser, к которому подключен прослушиватель аутентификации.

import React from 'react';
import { AuthUserContext } from '../Session/Index';
import { withFirebase } from '../Firebase/Index';



const withAuthentication = Component => {
  class WithAuthentication extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        authUser: null,
      };  
    }

    componentDidMount() {
      this.listener = this.props.firebase.auth.onAuthStateChanged(
        authUser => {
          authUser
            ? this.setState({ authUser })
            : this.setState({ authUser: null });
        },
      );
    }

    componentWillUnmount() {
      this.listener();
    };  

    render() {
      return (
        <AuthUserContext.Provider value={this.state.authUser}>
          <Component {...this.props} />
        </AuthUserContext.Provider>
      );
    }
  }
  return withFirebase(WithAuthentication);

};
export default withAuthentication;

Затем в потребительском компоненте у меня есть:

import React from 'react';
import {
    BrowserRouter as Router,
    Route,
    Link,
    Switch,
    useRouteMatch,
 } from 'react-router-dom';
import * as ROUTES from '../../constants/Routes';
import { compose } from 'recompose';
import { Divider, Layout, Card, Tabs, Typography, Menu, Breadcrumb, Icon } from 'antd';
import { withFirebase } from '../Firebase/Index';
import { AuthUserContext, withAuthorization, withEmailVerification } from '../Session/Index';




const { Title, Text } = Typography
const { TabPane } = Tabs;
const { Header, Content, Footer, Sider } = Layout;
const { SubMenu } = Menu;


class Dashboard extends React.Component {
  state = {
    collapsed: false,
    loading: false,
  };




  onCollapse = collapsed => {
    console.log(collapsed);
    this.setState({ collapsed });
  };

  render() {



    return (
    <AuthUserContext.Consumer>
      { authUser => (  

        <div>    

                 <Text style={{ float: 'right', color: "#fff"}}>
                 {/* 
                    { 
                      this.props.firebase.db.collection('users').doc(authUser.uid).get()
                      .then(doc => {
                          console.log( doc.data().name
)                          
                      })
                    } 
                  */} 

        </div>
      )}
    </AuthUserContext.Consumer>  
    );
  }
}

export default withFirebase(Dashboard);

Работает нормально при первой загрузке страницы.

Однако на странице refre sh система работает медленнее, чем код, и возвращает нулевые сообщения об ошибках, в которых говорится:

TypeError: Невозможно прочитать свойство 'uid' из null (анонимная функция)

Я видел эту статью , в которой предлагаются решения для Angular.

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

В статье предлагается:

firebase.auth().onAuthStateChanged( user =>; {
  if (user) { this.userId = user.uid }
});

Итак, в моем слушателе я попытался поставить перед authUser - но это не похоже на подход, который работает .

Любые советы о том, что делать дальше, чтобы сделать слушателя таким ets firebase загружает пользователя прежде, чем он выполнит проверку?

1 Ответ

2 голосов
/ 29 января 2020

Попробуйте response-with-firebase-auth этой библиотеки.
Эта библиотека делает доступной функцию withFirebaseAuth ().

import * as React from 'react';
import * as firebase from 'firebase/app';
import 'firebase/auth';

import withFirebaseAuth, { WrappedComponentProps } from 'react-with-firebase-auth';

import firebaseConfig from './firebaseConfig';

const firebaseApp = firebase.initializeApp(firebaseConfig);

const App = ({
  /** These props are provided by withFirebaseAuth HOC */
  signInWithEmailAndPassword,
  createUserWithEmailAndPassword,
  signInWithGoogle,
  signInWithFacebook,
  signInWithGithub,
  signInWithTwitter,
  signInAnonymously,
  signOut,
  setError,
  user,
  error,
  loading,
}: WrappedComponentProps) => (
  <React.Fragment>
    {
      user
        ? <h1>Hello, {user.displayName}</h1>
        : <h1>Log in</h1>
    }

    {
      user
        ? <button onClick={signOut}>Sign out</button>
        : <button onClick={signInWithGoogle}>Sign in with Google</button>
    }

    {
      loading && <h2>Loading..</h2>
    }
  </React.Fragment>
);

const firebaseAppAuth = firebaseApp.auth();

/** See the signature above to find out the available providers */
const providers = {
  googleProvider: new firebase.auth.GoogleAuthProvider(),
};
/** providers can be customised as per the Firebase documentation on auth providers **/
providers.googleProvider.setCustomParameters({hd:"mycompany.com"});

/** Wrap it */
export default withFirebaseAuth({
  providers,
  firebaseAppAuth,
})(App);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...