我设置了Firebase云功能以使用Express,还使用firebase SDK auth属性进行注册。我注意到,使用firebase-admin在firestore中创建新用户文档的管理员在部署后不会执行。
我使用邮递员尝试注册一个新用户,并从firebase收到此错误:
Error: Getting metadata from plugin failed with error: invalid_grant: Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values and use a clock with skew to account for clock differences between systems.
我该如何解决?
我创建了一个登录路由,该路由可以正常工作并返回令牌,因为它仅调用firebase SDK auth属性进行登录
这是我的项目代码:
初始化firebase-admin
const admin = require("firebase-admin");
const serviceAccount = require("./would-you-rather-app-c5895-firebase-adminsdk-lndjl-f7793c362b.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: `https://${serviceAccount.project_id}.firebaseio.com`
});
const db = admin.firestore();
module.exports = { admin, db };
表达设置
const functions = require('firebase-functions');
const app = require("express")();
// const cors = require("cors");
// app.use(cors());
const { signup, login } = require("./handlers/users");
// users routes
app.post("/signup", signup);
app.post("/login", login);
app.get("/", (request, response) => {
response.send("Hello from Firebase!");
});
exports.api = functions.https.onRequest(app);
用户注册和登录处理程序
const { admin, db } = require("../util/admin");
const config = require("../util/config");
const client = require("firebase");
client.initializeApp(config);
// Sign user up
exports.signup = (req, res) => {
const newUser = {
email: req.body.email,
password: req.body.password,
confirmPassword: req.body.confirmPassword,
firstName: req.body.firstName,
lastName: req.body.lastName,
fullname: `${req.body.firstName} ${req.body.lastName}`
};
// TODO: validation
const noImg = "no-img.png";
let userId, token;
client
.auth()
.createUserWithEmailAndPassword(newUser.email, newUser.password)
.then(data => {
userId = data.user.uid;
return data.user.getIdToken();
})
.then(idToken => {
token = idToken;
const userCredentials = {
fullname: newUser.fullname,
createdAt: new Date().toISOString(),
imageUrl: `https://firebasestorage.googleapis.com/v0/b/${
config.storageBucket
}/o/${noImg}?alt=media`,
score: 0,
questions: [],
votes: [],
userId: userId
};
return admin
.firestore()
.doc(`users/${userId}`)
.set(userCredentials);
})
.then(() => {
return res.status(201).json({ token });
})
.catch(err => {
console.log("Signup error: ", err);
if (err.code === "auth/email-already-in-use") {
return res.status(400).json({ email: "Email already in use" });
} else {
return res
.status(500)
.json({ general: "Something went wrong, please try agin" });
}
});
};
// Log user in
exports.login = (req, res) => {
const user = {
email: req.body.email,
password: req.body.password
};
client
.auth()
.signInWithEmailAndPassword(user.email, user.password)
.then(data => {
return data.user.getIdToken();
})
.then(token => {
return res.json({ token });
})
.catch(err => {
return res
.status(403)
.json({ general: "Wrong credentials, please try again" });
});
};
正在运行的注册会返回验证成功的错误,但用户凭据未添加到Firestore中...
Firebase-debug-log
[info] i functions: Beginning execution of "api"
[debug] [2019-06-10T17:40:33.997Z] Disabled runtime features: {"functions_config_helper":true,"network_filtering":true,"timeout":true,"memory_limiting":true,"protect_env":true,"admin_stubs":true}
[debug] [2019-06-10T17:40:35.600Z] firebase-admin has been stubbed.
[info] i Your code has been provided a "firebase-admin" instance.
[debug] [2019-06-10T17:40:36.599Z] Trigger "api" has been found, beginning invocation!
[debug] [2019-06-10T17:40:36.600Z]
[debug] [2019-06-10T17:40:36.600Z] Running api in mode HTTPS
[debug] [2019-06-10T17:40:36.612Z] {"socketPath":"\\\\?\\pipe\\C:\\Users\\ismail\\Documents\\Archive\\tutorial-codes\\NanoRD\\proj3\\proj3\\functions\\9796"}
[debug] [2019-06-10T17:40:36.617Z] [functions] Runtime ready! Sending request! {"socketPath":"\\\\?\\pipe\\C:\\Users\\ismail\\Documents\\Archive\\tutorial-codes\\NanoRD\\proj3\\proj3\\functions\\9796"}
[debug] [2019-06-10T17:40:36.660Z] Ephemeral server used!
[debug] [2019-06-10T17:40:36.717Z] Ephemeral server survived.
[info] > Signup error: Error: Getting metadata from plugin failed with error: invalid_grant: Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values and use a clock with skew to account for clock differences between systems.
[info] > at Http2CallStream.<anonymous> (C:\Users\ismail\Documents\Archive\tutorial-codes\NanoRD\proj3\proj3\functions\node_modules\@grpc\grpc-js\build\src\client.js:101:45)
[info] > at Http2CallStream.emit (events.js:201:15)
[info] > at C:\Users\ismail\Documents\Archive\tutorial-codes\NanoRD\proj3\proj3\functions\node_modules\@grpc\grpc-js\build\src\call-stream.js:71:22
[info] > at processTicksAndRejections (internal/process/task_queues.js:81:9) {
[info] > code: '400',
[info] > details: 'Getting metadata from plugin failed with error: invalid_grant: ' +
[info] > 'Invalid JWT: Token must be a short-lived token (60 minutes) and ' +
[info] > 'in a reasonable timeframe. Check your iat and exp values and use ' +
[info] > 'a clock with skew to account for clock differences between ' +
[info] > 'systems.',
[info] > metadata: Metadata { options: undefined, internalRepr: Map {} }
[info] > }
[info] i functions: Finished "api" in ~2s
我希望注册时返回一个令牌,并在firestore中存储一个新的用户凭证
答案 0 :(得分:1)
我遇到了这个问题,但这是由我的本地主机设置的无效时间引起的。
答案 1 :(得分:0)
我终于找到了一种同步计算机时钟的方法。这篇文章很有帮助:4 Ways to Automatically Synchronize Computer Clock on Windows Startup