我有一个React组件,用于控制到我的Firestore的授权帖子。用户提交基于文本的信息,然后使用axios作为客户端将其发送到Firebase。唯一的问题是,当我尝试提交数据时,出现以下错误:
Firebase ID令牌已过期。从您的客户端应用中获取新的ID令牌,然后重试”。
我怀疑getIdToken()
在客户端发送的令牌已过期,我不确定该如何解决。我尝试将其设置为getIdToken(true)
,该方法也不起作用。
到目前为止,唯一的“解决方案”是更改笔记本电脑的时间以匹配服务器的时区,这显然不是我要解决的问题。 因此,我只希望已登录的用户能够发布帖子而不会遇到此错误,请提供解决方案/建议。
这是GigRegister
组件中的axios帖子。
handleSubmit(e) {
let user = auth().currentUser.uid;
const gigData = {
name: this.state.name,
venue: this.state.venue,
time: this.state.time,
date: this.state.date,
genre: this.state.genre,
tickets: this.state.tickets,
price: this.state.price,
user: user
};
auth()
.currentUser.getIdToken()
.then(function (token) {
axios(
"https://us-central1-gig-fort.cloudfunctions.net/api/createGigListing",
{
method: "POST",
headers: {
"content-type": "application/json",
Authorization: "Bearer " + token,
},
data: gigData,
}
);
})
.then((res) => {
this.props.history.push("/Homepage");
})
.catch((err) => {
console.error(err);
});
}
...这是express / firebase函数。包括FBauth中间件:
const FBAuth = (req, res, next) => {
let idToken;
if(req.headers.authorization && req.headers.authorization.startsWith('Bearer ')){
idToken = req.headers.authorization.split('Bearer ')[1]
} else {
console.error('No token found')
return res.status(403).json({error: 'Unauthorized'})
}
admin.auth().verifyIdToken(idToken)
.then(decodedToken => {
req.user = decodedToken;
return db.collection('users')
.where('userId', '==',req.user.uid)
.limit(1)
.get()
})
.then(data =>{
req.user.venueName = data.docs[0].data().venueName;
return next();
})
.catch(err => {
console.error('Error while verifying token', err)
return res.status(403).json(err)
})
}
app.post('/createGigListing', FBAuth, (req,res) => {
const newGig = {
venueName: req.user.venueName,
name: req.body.name,
time: req.body.time,
price: req.body.price,
genre: req.body.genre,
tickets: req.body.tickets,
date: req.body.date,
user:req.body.user,
createdAt: new Date().toISOString()
}
db
.collection('gig-listing')
.add(newGig)
.then(doc => {
res.json({message: `document ${doc.id} created successfully`})
})
.catch(err =>{
res.status(500).json({error: 'something went wrong'})
console.error(err)
})
})
万一有人需要,这里是整个GigRegister
组件
import React from "react";
import Header from "./Header";
import TextField from "@material-ui/core/TextField";
import Button from "@material-ui/core/Button";
import axios from "axios";
import * as firebase from 'firebase'
import { auth } from 'firebase/app'
import {Link} from 'react-router-dom'
import UniqueVenueListing from './UniqueVenueListing'
class GigRegister extends React.Component {
constructor() {
super();
this.state = {
name: "",
venue: "",
time: "",
date: "",
genre: "",
tickets: "",
price: "",
userDetails: {},
filterGigs: [],
isLoggedIn:false,
currentToken:{}
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleChange(e) {
this.setState({
[e.target.name]: e.target.value,
});
}
handleClick() {
console.log("handle click reached");
auth()
.signOut()
.then(() => {
console.log("Successfully signed out");
})
.catch((err) => {
console.log(err);
});
}
authListener() {
auth().onAuthStateChanged((user) => {
if (user) {
this.setState(
{
userDetails: user
},
() =>
axios
.get(
"https://us-central1-gig-fort.cloudfunctions.net/api/getGigListings"
)
.then((res) => {
let filteredGigs = res.data.filter((gig) => {
return gig.user === this.state.userDetails.uid;
});
this.setState({
filterGigs: filteredGigs
});
})
);
} else {
this.setState({
userDetails: null,
});
console.log("no user signed in");
}
});
}
componentDidMount() {
this.authListener();
}
handleSubmit(e) {
let user = auth().currentUser.uid;
const gigData = {
name: this.state.name,
venue: this.state.venue,
time: this.state.time,
date: this.state.date,
genre: this.state.genre,
tickets: this.state.tickets,
price: this.state.price,
user: user
};
auth()
.currentUser.getIdToken()
.then(function (token) {
axios(
"https://us-central1-gig-fort.cloudfunctions.net/api/createGigListing",
{
method: "POST",
headers: {
"content-type": "application/json",
Authorization: "Bearer " + token,
},
data: gigData,
}
);
})
.then((res) => {
this.props.history.push("/Homepage");
})
.catch((err) => {
console.error(err);
});
}
render() {
return (
<div className="gig-register">
<Header />
<div className="heading-container">
<h1>Venue Dashboard</h1> <br></br>
{this.state.userDetails ? (
<h3>You are signed in as {this.state.userDetails.email}</h3>
) : null}
<div className="gig-reg-buttons">
{this.state.userDetails ? (
<Button onClick={this.handleClick}>Sign out </Button>
) : (
<Link to="/" style={{ textDecoration: "none" }}>
<Button>Sign In</Button>
</Link>
)}
<Link to="/Homepage" style={{ textDecoration: "none" }}>
<Button>Go to gig listings</Button>
</Link>
</div>
</div>
<div className="handle-gigs">
<div className="reg-gig-input">
<form onSubmit={this.handleSubmit}>
<h3>Register a gig</h3>
<br></br>
<TextField
placeholder="Event name"
defaultValue="Event name"
id="name"
name="name"
onChange={this.handleChange}
/>
<TextField
placeholder="Time"
defaultValue="Time"
type="time"
label="Enter start time"
id="time"
name="time"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
onChange={this.handleChange}
/>
<TextField
id="date"
label="Select date"
type="date"
defaultValue="2017-05-24"
InputLabelProps={{
shrink: true,
}}
onChange={(e) => {
this.setState({ date: e.target.value });
}}
/>
<TextField
placeholder="Genre"
defaultValue="Genre"
id="genre"
name="genre"
onChange={this.handleChange}
/>
<TextField
placeholder="Tickets"
defaultValue="Tickets"
id="tickets"
name="tickets"
onChange={this.handleChange}
/>
<TextField
placeholder="Price"
defaultValue="Price"
id="price"
name="price"
onChange={this.handleChange}
/>
<Button type="submit">Submit</Button>
</form>
</div>
<div className="manage-gigs">
<h3 className="manage-gig">Manage your gigs</h3>
<br></br>
{this.state.userDetails ? (
<UniqueVenueListing gigList={this.state.filterGigs} />
) : (
<h2>no gigs to show</h2>
)}
</div>
</div>
</div>
);
}
}
export default GigRegister