Я знаю, что этот вопрос задавался в других контекстах. Я прочитал эти ответы. Я попробовал ответы. Я прочитал документы по Firebase. Так что пока это не помогает. Я новичок в пожарной части. Изучите, как использовать продукт, изучив руководство по совместному использованию React и Firebase. Создание модуля аутентификации / авторизации для пользователей. Может успешно зарегистрировать / зарегистрировать пользователя и увидеть результаты как в модуле авторизации, так и в базе данных в реальном времени в обзоре проекта Firebase. Когда пользователь выходит из системы, проверка RDb подтверждает, что все свойства данных сохраняются. Когда пользователь снова входит в систему (электронная почта / пароль), проверка RDb показывает, что в RDb сохраняются только uid и адрес электронной почты. Неавторизованные свойства пользователя, такие как имя пользователя и роль, становятся пустыми строками или объектами, присутствующими, но не заполненными. Я провел значительное чтение документации по Firebase и отладку кода, но не могу определить, почему это происходит, и поэтому не могу определить, как это исправить.
Вот некоторые сегменты кода:
Первый модуль firebase:
import app from 'firebase/app'
import 'firebase/auth'
import 'firebase/database'
... set up the config ...
// set the config constant to the appropriate value
const config = process.env.NODE_ENV === 'production' ? prodConfig : devConfig
class Firebase {
constructor() {
// initialize the app using the Firebase config to instatiate all of the firebase services
app.initializeApp(config)
// instantiate the initial auth state within the app
this.auth = app.auth() // Gets the Auth service for the current app
// instantiate the database within the app
this.db = app.database() // Gets the Database service for the current app
console.log('this.db ', this.db)
// Social media login providers (authorization methods within Firebase)
this.googleProvider = new app.auth.GoogleAuthProvider()
this.facebookProvider = new app.auth.FacebookAuthProvider()
this.twitterProvider = new app.auth.TwitterAuthProvider()
}
... the comments are mostly for my benefit ...
// ***** Firebase Auth API *****
// create user with email and password (equate doCreate... with Firebase createUser...)
doCreateUserWithEmailAndPassword = ( email, password ) => this.auth.createUserWithEmailAndPassword( email, password )
// ***** SignIn with email ***** (equate doSignIn... with Firebase signIn...)
doSignInWithEmailAndPassword = ( email, password ) => this.auth.signInWithEmailAndPassword( email, password )
// ***** SignIn with facebook ***** (equate as above)
doSignInWithFacebook = () => this.auth.signInWithPopup( this.facebookProvider )
// ***** SignIn with google ***** (equate as above)
doSignInWithGoogle = () => this.auth.signInWithPopup( this.googleProvider )
// ***** SignIn with twitter ***** (equate as above)
doSignInWithTwitter = () => this.auth.signInWithPopup( this.twitterProvider )
// ***** SignOut ***** (equate as above)
doSignOut = () => this.auth.signOut()
// ***** Password Reset ***** (equate as above)
doPasswordReset = email => this.auth.sendPasswordResetEmail( email )
// ***** Password Update ***** (equate as above)
doPasswordUpdate = password => this.auth.currentUser.updatePassword( password )
// ***** User API *****
// set the current user id
user = uid => this.db.ref(`users/${uid}`)
// set the reference to the users collection in the firebase database
users = () =>this.db.ref('users')
// ***** Merge Auth and DB User API *****
... big block of comments to me ...
onAuthUserListener = (next, fallback) =>
this.auth.onAuthStateChanged(authUser => {
if ( authUser ) {
this.user(authUser.uid)
.once('value')
.then(snapshot => {
const dbUser = snapshot.val()
console.log('this.user ',this.user)
console.log('dbUser ',dbUser)
// default empty roles
if ( !dbUser.roles ) {
dbUser.roles = {}
}
// merge auth and db user
this.db.ref(`users/${this.user}`).set({
uid: authUser.uid,
email: authUser.email,
username: authUser.username,
roles: authUser.roles,
...dbUser,
})
console.log('firebase.js authUser ', authUser)
next(authUser)
})
} else { // there is no authUser
fallback()
}
})
}
export default Firebase
Вот компонент Sign UP:
// index.js - SignUp
// the entry point for the SignUp component
import React, { Component } from 'react'
import { Link, withRouter } from 'react-router-dom'
import { compose } from 'recompose'
import { Typography, Input, Checkbox, FormLabel, Button } from '@material-ui/core'
import { withFirebase } from '../Firebase'
import * as ROUTES from '../../constants/routes'
import * as ROLES from '../../constants/roles'
import '../../styles/auth.css'
const SignUpPage = () => (
<div id='wrapper' className='signup-page'>
<SignUpForm />
</div>
)
// initialize the state of the component using destructuring
// allows INITIAL_STATE to be reset after successful SignUp
const INITIAL_STATE = {
username: '',
email: '',
passwordOne: '',
passwordTwo: '',
isAdmin: false,
error: null,
}
class SignUpFormBase extends Component {
constructor(props) {
super(props)
// spread operator (...) spreads out to reach all properties individually
this.state = { ...INITIAL_STATE }
}
onSubmit = event => {
// get necessary info from this.state to pass to the Firebase authentication API
const { username, email, passwordOne, isAdmin } = this.state
const roles = {}
if ( isAdmin ) { roles[ROLES.ADMIN] = ROLES.ADMIN } // set roles if the admin checkbox is checked
this.props.firebase
// create a user (limited access) in the authentication database
.doCreateUserWithEmailAndPassword( email, passwordOne )
// successful
.then( authUser => {
// create a user in Firebase realtime database -- this is where you manage user properties
// because in the firebase auth module, users cannot be manipulated.
console.log('signup authUser ',authUser)
return this.props.firebase
.user(authUser.user.uid) // use the authUser.uid to:
.set({ username, email, roles }) // write username, email & roles to the rdb
})
.then(() => {
// update state and redirect to Home page
this.setState({ ...INITIAL_STATE })
this.props.history.push(ROUTES.HOME)
})
// error - setState, error (if something is wrong)
.catch(error => {
this.setState({ error })
})
// prevent default behavior (a reload of the browser)
event.preventDefault()
}
onChange = event => {
// dynamically set state properties when they change, based on which input call is executed
// each <input> element (in the return) operates on a different property of state (according to value)
this.setState({ [event.target.name]: event.target.value })
}
onChangeCheckbox = event => {
this.setState({ [event.target.name]: event.target.checked })
}
render() {
// parse each of the values from current state
const {
username,
email,
passwordOne,
passwordTwo,
isAdmin,
error
} = this.state
// list of invalid conditions for which to check (validation of form elements)
const isInvalid =
passwordOne !== passwordTwo ||
passwordOne === '' ||
email === '' ||
username === ''
return (
// the input form -- with fields (username, email, passwordOne, passwordTwo)
<div className='container'>
<Typography
variant='h6'
align = 'center'
className='item'
>
Sign Up Page
</Typography>
<br />
<form className='signup-form item' onSubmit={ this.onSubmit }>
<Input
className='item'
name='username'
value={username}
onChange={this.onChange}
type='text'
placeholder='Full Name'
/>
... input email, password, confirm password, checkbox to designate Admin ...
<Button
variant='contained'
className='item btn btn-secondary'
disabled={ isInvalid }
type='submit'
>
Sign Up
</Button>
{/* if there is an error (a default Firebase property), render the error message */}
{error && <p>{ error.message }</p>}
</form>
</div>
)
}
}
const SignUpLink = () => (
<Typography
variant = 'body1'
align = 'center'
className = 'item'
>
Don't have an account? <Link to={ ROUTES.SIGN_UP }>Sign Up</Link>
</Typography>
)
const SignUpForm = compose(withRouter, withFirebase)(SignUpFormBase)
export default SignUpPage
export { SignUpForm, SignUpLink }
Вот компонент Sign IN (электронная почта / пароль):
// SignInEmail.js - SignIn
// the email/password SignIn component
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
import { compose } from 'recompose'
import { Typography, Input } from '@material-ui/core'
import Button from 'react-bootstrap/Button'
import { withFirebase } from '../Firebase'
import * as ROUTES from '../../constants/routes'
// initialize the state of the component using destructuring
// allows INITIAL_STATE to be reset after successful SignUp
const INITIAL_STATE = {
username: '',
email: '',
password: '',
roles: {},
error: null,
}
// ======================================
// ***** signin with email/password *****
// ======================================
class SignInEmailBase extends Component {
constructor(props) {
super(props)
// spread operator (...) spreads out to reach all properties individually
this.state = {
...INITIAL_STATE
}
}
onSubmit = event => {
// get necessary info from this.state to pass to the Firebase authentication API
// const { username, email, password, roles } = this.state
const { username, email, password, roles } = this.state
this.props.firebase
// execute SignIn function (create a user)
.doSignInWithEmailAndPassword( email, password )
// successful
.then(authUser => {
// create a user in Firebase Realtime database
console.log('signin authUser ',authUser)
return this.props.firebase
.user(authUser.user.uid)
.set({ username, email, roles })
})
.then(() => {
// update state and redirect to Home page
this.setState({ ...INITIAL_STATE })
this.props.history.push(ROUTES.HOME)
})
// error - setState, error (if something is wrong)
.catch(error => {
this.setState({
error
})
})
// prevent default behavior (a reload of the browser)
event.preventDefault()
}
onChange = event => {
// dynamically set state properties when they change, based on which input call is executed
// each <input> element (in the return) operates on a different property of state (according to value)
this.setState({ [event.target.name]: event.target.value })
}
render() {
// parse each of the values from current state
const { email, password, error } = this.state
// list of invalid conditions for which to check (validation of form elements)
const isInvalid = password === '' || email === ''
return (
// the input form -- with fields (username, email, passwordOne, passwordTwo)
<div className = 'container signin-page'>
<Typography
variant = 'h6'
align = 'center'
className = 'item'
>
Sign In Page
</Typography>
<br />
<form className = 'item email-form' onSubmit = { this.onSubmit} >
... input email, password...
{ /* disable the button if the form is invalid -- see isInvalid above */ }
<Button
className = 'item btn btn-secondary'
type = 'submit'
disabled = { isInvalid }
>
SIGN IN WITH EMAIL
</Button>
{ /* if there is an error (a default Firebase property), render the error message */ }
{ error && <p> { error.message } </p> }
</form>
</div>
)
}
}
const SignInEmail = compose(withRouter, withFirebase, )(SignInEmailBase)
export default SignInEmail
Вот скриншот просмотра браузера и скриншот записи базы данных в реальном времени после регистрации
Здесь тот же пользователь после выхода и входа - никаких других манипуляций с данными
Я уверен, что мог бы помочь. Спасибо.