将 Firebase SDK 与 Netlify Lambda 函数结合使用
Use Firebase SDK with Netlify Lambda Functions
我创建了一个使用 React + Firebase + Lambda 函数的项目。
我在前端有 Firebase 代码,我需要一些后端来处理一些事件。 ()
当我使用 Netlify 部署我的应用程序时,我可以使用 netlify-lambda 访问 Amazon Lambda Functions。 (https://www.netlify.com/docs/functions/)
通常一切正常(mailchimp API、snipcart API 等...)
但是我无法让 Firebase 工作。
我创建了一个具有读写权限的服务帐户。
这是我的 lambda 函数的代码:
(只是尝试查看数据库的用户部分的测试。)
import firebaseAdmin from 'firebase-admin'
const serviceAccount = require('../utils/FirebaseServiceAccountKey.json')
export function handler (event, context, callback) {
firebaseAdmin.initializeApp({
credential: firebaseAdmin.credential.cert(serviceAccount),
databaseURL: 'https://sample-3615.firebaseio.com'
})
const db = firebaseAdmin.database()
const ref = db.ref('/users')
let users = {}
ref.once('value', function (snapshot) {
console.log(snapshot.val())
users = snapshot.val()
})
callback(null, {
statusCode: 200,
body: JSON.stringify({ users })
})
}
它 returns 我 : TypeError: rtdb.initStandalone is not a function
.
我也有很多像这样的警告:Module not found: Error: Can not resolve 'memcpy'
和其他软件包。
我对组件中函数的调用:
handleClick = (e) => {
e.preventDefault()
this.setState({loading: true})
fetch('/.netlify/functions/score')
.then(res => res.json())
.then(json => console.log(json.users))
.then(() => this.setState({loading: false}))
}
我不确定问题出在哪里。网络包?
我无法使用来自 Netlify 的 AWS Lambda 运行 SDK。
要使用 Netlify Lambda 函数中的 Firebase,我将使用管理员权限通过 REST API。
https://firebase.google.com/docs/reference/rest/database/
它像这样完美地工作。
import { google } from 'googleapis'
import fetch from 'node-fetch'
const serviceAccount = require('../utils/FirebaseServiceAccountKey.json')
const scopes = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/firebase.database'
]
// Authenticate a JWT client with the service account.
const jwtClient = new google.auth.JWT(
serviceAccount.client_email,
null,
serviceAccount.private_key,
scopes
)
export function handler (event, context, callback) {
const res = JSON.parse(event.body)
// Use the JWT client to generate an access token.
jwtClient.authorize(async function (error, tokens) {
if (error) {
console.log('Error making request to generate access token:', error)
} else if (tokens.access_token === null) {
console.log('Provided service account does not have permission to generate access tokens')
} else {
const accessToken = tokens.access_token
const score = await fetch(`https://example-3615.firebaseio.com/scores/${res.uid}/score.json`)
.then(data => data.json())
.then(score => score + res.score)
fetch(`https://example-3615.firebaseio.com/scores/${res.uid}.json?access_token=${accessToken}`, {
body: JSON.stringify({ score, displayName: res.user.displayName, photoURL: res.user.photoURL }),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: 'PATCH'
})
.then(() => {
callback(null, {
statusCode: 200,
body: 'Score +1'
})
})
}
})
}
问题出在 "webpack.server.js" 配置文件中。 netlify-lambda 用于捆绑 server-side 代码(功能代码),由于某些原因,它捆绑不正确。
所以我将新文件添加到项目根目录 "webpack.server.js":
//webpack.config.js
const path = require('path');
const pkg = require('./package')
const GenerateJsonPlugin = require('generate-json-webpack-plugin')
const externals = [
'firebase-admin'
]
const genPackage = () => ({
name: 'functions',
private: true,
main: 'index.js',
license: 'MIT',
dependencies: externals.reduce(
(acc, name) =>
Object.assign({}, acc, {
[name]:
pkg.dependencies[name] ||
pkg.devDependencies[name]
}),
{}
)
})
module.exports = {
target: 'node',
resolve: {
mainFields: ['module', 'main']
},
externals: externals.reduce(
(acc, name) => Object.assign({}, acc, { [name]: true }),
{}
),
plugins: [new GenerateJsonPlugin('package.json', genPackage())]
}
此文件配置将创建一个新的 package.json 文件,放置在 lambda dist 中。
更新
在 Medium (Firebase Admin with Netlify lambda functions)
上查看我的 post
我创建了一个使用 React + Firebase + Lambda 函数的项目。
我在前端有 Firebase 代码,我需要一些后端来处理一些事件。 (
当我使用 Netlify 部署我的应用程序时,我可以使用 netlify-lambda 访问 Amazon Lambda Functions。 (https://www.netlify.com/docs/functions/)
通常一切正常(mailchimp API、snipcart API 等...)
但是我无法让 Firebase 工作。
我创建了一个具有读写权限的服务帐户。
这是我的 lambda 函数的代码: (只是尝试查看数据库的用户部分的测试。)
import firebaseAdmin from 'firebase-admin'
const serviceAccount = require('../utils/FirebaseServiceAccountKey.json')
export function handler (event, context, callback) {
firebaseAdmin.initializeApp({
credential: firebaseAdmin.credential.cert(serviceAccount),
databaseURL: 'https://sample-3615.firebaseio.com'
})
const db = firebaseAdmin.database()
const ref = db.ref('/users')
let users = {}
ref.once('value', function (snapshot) {
console.log(snapshot.val())
users = snapshot.val()
})
callback(null, {
statusCode: 200,
body: JSON.stringify({ users })
})
}
它 returns 我 : TypeError: rtdb.initStandalone is not a function
.
我也有很多像这样的警告:Module not found: Error: Can not resolve 'memcpy'
和其他软件包。
我对组件中函数的调用:
handleClick = (e) => {
e.preventDefault()
this.setState({loading: true})
fetch('/.netlify/functions/score')
.then(res => res.json())
.then(json => console.log(json.users))
.then(() => this.setState({loading: false}))
}
我不确定问题出在哪里。网络包?
我无法使用来自 Netlify 的 AWS Lambda 运行 SDK。
要使用 Netlify Lambda 函数中的 Firebase,我将使用管理员权限通过 REST API。
https://firebase.google.com/docs/reference/rest/database/
它像这样完美地工作。
import { google } from 'googleapis'
import fetch from 'node-fetch'
const serviceAccount = require('../utils/FirebaseServiceAccountKey.json')
const scopes = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/firebase.database'
]
// Authenticate a JWT client with the service account.
const jwtClient = new google.auth.JWT(
serviceAccount.client_email,
null,
serviceAccount.private_key,
scopes
)
export function handler (event, context, callback) {
const res = JSON.parse(event.body)
// Use the JWT client to generate an access token.
jwtClient.authorize(async function (error, tokens) {
if (error) {
console.log('Error making request to generate access token:', error)
} else if (tokens.access_token === null) {
console.log('Provided service account does not have permission to generate access tokens')
} else {
const accessToken = tokens.access_token
const score = await fetch(`https://example-3615.firebaseio.com/scores/${res.uid}/score.json`)
.then(data => data.json())
.then(score => score + res.score)
fetch(`https://example-3615.firebaseio.com/scores/${res.uid}.json?access_token=${accessToken}`, {
body: JSON.stringify({ score, displayName: res.user.displayName, photoURL: res.user.photoURL }),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: 'PATCH'
})
.then(() => {
callback(null, {
statusCode: 200,
body: 'Score +1'
})
})
}
})
}
问题出在 "webpack.server.js" 配置文件中。 netlify-lambda 用于捆绑 server-side 代码(功能代码),由于某些原因,它捆绑不正确。 所以我将新文件添加到项目根目录 "webpack.server.js":
//webpack.config.js
const path = require('path');
const pkg = require('./package')
const GenerateJsonPlugin = require('generate-json-webpack-plugin')
const externals = [
'firebase-admin'
]
const genPackage = () => ({
name: 'functions',
private: true,
main: 'index.js',
license: 'MIT',
dependencies: externals.reduce(
(acc, name) =>
Object.assign({}, acc, {
[name]:
pkg.dependencies[name] ||
pkg.devDependencies[name]
}),
{}
)
})
module.exports = {
target: 'node',
resolve: {
mainFields: ['module', 'main']
},
externals: externals.reduce(
(acc, name) => Object.assign({}, acc, { [name]: true }),
{}
),
plugins: [new GenerateJsonPlugin('package.json', genPackage())]
}
此文件配置将创建一个新的 package.json 文件,放置在 lambda dist 中。
更新 在 Medium (Firebase Admin with Netlify lambda functions)
上查看我的 post