Я создаю приложение для опросов, где студенты могут задавать вопросы и отвечать на них. Для этого я выполнил некоторые базовые c аутентификации, а также маршрутизацию. Вот моя проблема: хотя маршрутизация работает, когда я использую запуск пряжи и просматриваю проект на локальном сервере, он не работает полностью, когда я развертываю его в firebase. В частности, компоненты «Signin», «SignUp» и «ForgotPassword» отображаются как на локальном хосте, так и в развертывании firebase, но компоненты «PollBoard» и «UserComponent» работают только на локальном хосте.
Я также получаю эту ошибку в firebase при маршрутизации на дом (или в компонент PollBoard)
f (...): ничего не было возвращено при рендеринге. Обычно это означает, что оператор return> отсутствует. Или, чтобы ничего не отобразить, верните null.
Вот индекс. js, маршруты. js, а также база данных. json, отвечающая за представление и маршрутизацию проекта. :
База огня. json
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "build",
"headers": [
{"source": "/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}]}
],
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
Индекс. js
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter as Router} from 'react-router-dom';
import Routes from './Routes.js';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
//only routes is rendered, as a router type
<Router>
<div>
<Routes/>
</div>
</Router>,
document.getElementById('root')
);
serviceWorker.unregister();
Маршруты. js
import React, { Component } from "react";
import { Router, Switch, Route, BrowserRouter } from "react-router-dom";
import fire from './config/Fire.js';
import {ProtectedRoute} from './ProtectedRoute';
import history from './history';
import Signin from "./Signin";
import PollBoard from "./PollBoard";
import UserComponent from "./UserComponent";
import SignUp from './SignUp';
import ForgotPassword from './ForgotPassword';
//Routes is essentially the central director of the website
//It's like a working directory that also checks whether or not the user is authenticated
//The default route is always the sign in component and everythign else moves from there
class Routes extends Component {
constructor(props){
super(props);
this.state = {
//this is the user object that is changed when the auth changes
user:{},
};
}
//activates the authListener
componentDidMount(){
this.authListener();
}
//The auth listener basically waits to see if the user has logged on
authListener(){
fire.auth().onAuthStateChanged((user) => {
// console.log(user);
if(user){
this.setState({user});
// localStorage.setItem('user', user.uid);
}
else{
this.setState({user: null});
// localStorage.removeItem('user');
}
});
}
render() {
return (
<div className = "App">
<BrowserRouter history = {history}>
{/* <Router history={history}> */}
<Switch>
{/* "/" is the path that is rendered by default */}
<Route exact path="/" component={Signin} />
<Route path="/SignUp" component={SignUp} />
<Route path="/ForgotPassword" component={ForgotPassword} />
{/* "Protected routes are all accessible if and only if the user has signed in*/}
<ProtectedRoute exact path="/Home" component={PollBoard} />
<ProtectedRoute exact path="/Profile" component={UserComponent} />
</Switch>
{/* </Router> */}
</BrowserRouter>
</div>
)
}
}
export default Routes;
Здесь Вот некоторые из компонентов:
PollBoard
import React, { Component } from 'react';
import { Map } from 'immutable';
import PollComponent from './PollComponent';
import './App.css';
import fire from './config/Fire';
import { auth } from 'firebase';
class PollBoard extends Component {
constructor(props) {
super(props);
this.state = {polls: Map(), pollID: 0, newPollQuestion: "", newPollChoices: "", newPollCategory: "", newPollTimeLimit: "", newPollUser: ""};
//bind all methods
this.logout = this.logout.bind(this);
this.routeProfile = this.routeProfile.bind(this);
this.fetchedPolls = this.fetchedPolls.bind(this);
this.newPollQuestionFunction = this.newPollQuestionFunction.bind(this);
this.newPollChoicesFunction = this.newPollChoicesFunction.bind(this);
this.newPollCategoryFunction = this.newPollCategoryFunction.bind(this);
this.newPollTimeLimitFunction = this.newPollTimeLimitFunction.bind(this);
this.newPollUserFunction = this.newPollUserFunction.bind(this);
this.savePollInfo = this.savePollInfo.bind(this);
this.delete = this.delete.bind(this);
this.save = this.save.bind(this);
this.render = this.render.bind(this);
}
//I am adding a logout function here
//apologies in advance if it messes something up
logout = () => {
fire.auth().signOut();
}
routeProfile = () => {
this.props.history.push("/Profile");
}
fetchedPolls = (allPolls) => {
this.setState({polls: allPolls});
}
newPollQuestionFunction = (event) => {
this.setState({newPollQuestion: event.target.value})
}
newPollChoicesFunction = (event) => {
this.setState({newPollChoices: event.target.value})
}
newPollCategoryFunction = (event) => {
this.setState({newPollCategory: event.target.value})
}
newPollTimeLimitFunction = (event) => {
this.setState({newPollTimeLimit: event.target.value})
}
newPollUserFunction = (event) => {
this.setState({newPollUser: event.target.value})
}
savePollInfo = () => {
var pollData = {
PollQuestion: this.state.newPollQuestion,
PollChoices: this.state.newPollChoices,
PollCategory: this.state.newPollCategory,
PollTimeLimit: this.state.newPollTimeLimit,
PollUser: this.state.newPollUser
}
this.setState({
polls: this.state.polls.set(this.state.ID, pollData),
pollID: this.state.pollID +1,
})
}
delete = (pollID) => {
this.setState({polls: this.state.polls.delete(pollID)})
}
save = (id, field) => {
this.setState({polls:this.state.polls.update(id, (n) => { return Object.assign({}, n, field); })})
console.log(field)
}
render() {
const allPolls = this.state.polls.entrySeq().map(([id, poll]) => {
console.log(poll)
return <PollComponent save = {this.save} delete = {this.delete} PollQuestion={poll.PollQuestion} PollChoices = {poll.PollChoices} PollCategory = {poll.PollCategory} PollTimeLimit = {poll.PollTimeLimit} PollUser = {poll.PollUser} id={id}/>
}
)
return (
// <body>
<div>
<p> This is the Poll Board </p>
<p onClick = {this.routeProfile}>Click here to visit my profile</p>
<p> Add a Poll </p>
<p>Enter Question</p>
<input placeholder= "Question?" type = "text" value={this.state.newPollQuestion} onChange={this.newPollQuestionFunction}/>
<p>Enter Answer Choices</p>
<input placeholder= "Answer Choices?" type = "text" value={this.state.newPollChoices} onChange={this.newPollChoicesFunction}/>
<p>Enter Poll Category</p>
<input placeholder= "Category?" type = "text" value={this.state.newPollCategory} onChange={this.newPollCategoryFunction}/>
<p>Enter Time Limit</p>
<input placeholder= "Time Limit?" type = "text" value={this.state.newPollTimeLimit} onChange={this.newPollTimeLimitFunction}/>
<p>Enter User</p>
<input placeholder= "User?" type = "text" value={this.state.newPollUser} onChange={this.newPollUserFunction}/>
<div className = "post">
<button onClick={this.savePollInfo}>Post Poll</button>
</div>
<div>
{allPolls}
</div>
<p onClick = {this.logout}> logout </p>
</div>
// </body>
)
}
}
export default PollBoard;
UserComponent
import React, { Component } from 'react';
import fire from './config/Fire';
class UserComponent extends Component{
//this will essentially be the profile section
constructor(props){
super(props);
this.state = {displayProfile: true, username: "", password: "", email: "", classyear: ""}
}
changeDisplay = () =>{
this.setState({displayProfile: !this.state.displayProfile})
}
//methods that pull as the user information from the DB
//************ */
//the profile section should essentially display either the indivials info, or their myPolls
render(){
var basicProfile = (
<div>
<h1>Profile</h1>
<p>Email: {this.state.email}</p>
<p>Username: {this.state.username}</p>
<p>Password: {this.state.password}</p>
<p>Class Year: {this.state.classyear}</p>
<h1 onClick ={this.changeDisplay}>View My Polls</h1>
</div>
);
var myPolls =(
<div>
<h1>My Polls</h1>
<p onClick ={this.changeDisplay}>My Profile</p>
{/* need some way of pulling all of the users previous polls form the db */}
</div>
);
var displayedScreen = null;
if(!this.state.displayProfile){
displayedScreen = myPolls;
}
else{
displayedScreen = basicProfile;
}
return(
<div>
{displayedScreen}
</div>
);
}
}
export default UserComponent;
Вход
import React, { Component } from 'react';
import { Map } from 'immutable';
import PollComponent from './PollComponent';
import fire from './config/Fire.js';
import {withRouter} from 'react-router-dom';
class Signin extends Component{
constructor(props){
super(props);
//binding all methods
this.login = this.login.bind(this);
this.inputPassword = this.inputPassword.bind(this);
this.inputEmail = this.inputEmail.bind(this);
this.createNewProfile = this.createNewProfile.bind(this);
this.changeForgotPassword = this.changeForgotPassword.bind(this);
this.signUp = this.signUp.bind(this);
//for now just four essential variables as well as mypolls (not sure how to incorporate that)
this.state = {
forgotpassword:false,
newprofile: false,
password: "",
email: "",
};
}
inputPassword = (event) => {
this.setState({password: event.target.value})
}
inputEmail = (event) => {
this.setState({email: event.target.value})
}
createNewProfile = (event) => {
// this.setState({newprofile: true})
this.props.history.push("/SignUp");
}
changeForgotPassword = (event) => {
// this.setState({forgotpassword:true})
this.props.history.push("/ForgotPassword");
}
//auth based login function
login = (e) => {
e.preventDefault();
//authenticate the user with firebases methods
fire.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then((u) =>{
}).catch((error) =>{
console.log(error);
});
if(fire.auth().currentUser){
this.props.history.push("/Home");
}
}
signUp = (e) =>{
//sign the user up using firebase methods
e.preventDefault();
fire.auth().createUserWithEmailAndPassword(this.state.email, this.state.password).catch((error) =>{
console.log(error);
})
}
render(){
var passwordBox = null;
var emailBox = null;
passwordBox = (
<div>
<input value = {this.state.password} onChange ={this.inputPassword} />
</div>
)
emailBox = (
<div>
<input value = {this.state.email} onChange ={this.inputEmail} />
</div>
)
var userDisplay = (
<div>
<h1> DartPoll</h1>
{emailBox}
{passwordBox}
<button onClick = {this.login}> Login</button>
<p onClick = {this.changeForgotPassword}>Forgot password</p>
<p onClick ={this.createNewProfile}>Create a new account</p>
</div>
);
// if(this.state.newprofile){
// userDisplay = (
// <div>
// <h1> DartPoll</h1>
// <p>Create a new account</p>
// {emailBox}
// {passwordBox}
// <button onClick = {this.signUp}> Create</button>
// </div>
// )
// }
// if(this.state.forgotpassword){
// userDisplay = (
// <div>
// <h1> DartPoll</h1>
// <p>Enter in your email</p>
// {emailBox}
// <p> Enter in the new password you would like to use</p>
// {passwordBox}
// <button> Change Password</button>
// </div>
// )
// }
return (
<div>
{userDisplay}
</div>
)
}
}
export default Signin;
Регистрация
import React, { Component } from 'react';
import { Map } from 'immutable';
import PollComponent from './PollComponent';
import fire from './config/Fire.js';
import {withRouter} from 'react-router-dom';
class SignUp extends Component{
constructor(props){
super(props);
this.state = {email: "", password: ""}
//bind methods
this.inputEmail = this.inputEmail.bind(this);
this.inputPassword = this.inputPassword.bind(this);
this.signUp = this.signUp.bind(this);
}
inputPassword = (event) => {
this.setState({password: event.target.value})
}
inputEmail = (event) => {
this.setState({email: event.target.value})
}
signUp(e){
e.preventDefault();
fire.auth().createUserWithEmailAndPassword(this.state.email, this.state.password).catch((error) =>{
console.log(error);
})
if(fire.auth().currentUser){
this.props.history.push("/Home");
}
}
render(){
var passwordBox = null;
var emailBox = null;
passwordBox = (
<div>
<input value = {this.state.password} onChange ={this.inputPassword} />
</div>
)
emailBox = (
<div>
<input value = {this.state.email} onChange ={this.inputEmail} />
</div>
)
var userDisplay = (
<div>
<h1> DartPoll</h1>
<p>Create a new account</p>
{emailBox}
{passwordBox}
<button onClick = {this.signUp}> Create</button>
</div>
)
return(
<div>
{userDisplay}
</div>
);
}
}
export default SignUp;
ForgotPassword
import React, { Component } from 'react';
import { Map } from 'immutable';
import PollComponent from './PollComponent';
import fire from './config/Fire.js';
import {withRouter} from 'react-router-dom';
class ForgotPassword extends Component{
constructor(props){
super(props);
this.state = {email: "", password: ""}
//bind methods
this.inputPassword = this.inputPassword.bind(this);
this.inputEmail = this.inputEmail.bind(this);
this.signUp = this.signUp.bind(this);
}
inputPassword = (event) => {
this.setState({password: event.target.value})
}
inputEmail = (event) => {
this.setState({email: event.target.value})
}
signUp = (e) =>{
e.preventDefault();
fire.auth().createUserWithEmailAndPassword(this.state.email, this.state.password).catch((error) =>{
console.log(error);
})
if(fire.auth().currentUser){
this.props.history.push("/Home");
}
}
render(){
var passwordBox = null;
var emailBox = null;
passwordBox = (
<div>
<input value = {this.state.password} onChange ={this.inputPassword} />
</div>
)
emailBox = (
<div>
<input value = {this.state.email} onChange ={this.inputEmail} />
</div>
)
var userDisplay = (
<div>
<h1> DartPoll</h1>
<p>Forget Your Password? Simply Change It</p>
{emailBox}
{passwordBox}
<button onClick = {this.signUp}> Create</button>
</div>
)
return(
<div>
{userDisplay}
</div>
);
}
}
export default ForgotPassword;
Чтобы повторить, все компоненты, маршрутизация и рендеринг работают на локальном хосте с запуском пряжи, но не все рендерится в firebase. Вот несколько картинок, которые дополнительно демонстрируют проблему. Любая помощь будет очень признательна.