typescript - Firebase Cloud Functions with Typescript,如何转换复杂的界面
问题描述
在应用程序端,我可以查询集合并将结果自动转换为接口。Positions 有一个构造函数,它接收接口 IPosition。
似乎在云功能方面做同样的事情不允许部署功能。很难调试代码,因为它必须被部署并且仅在代码工作时才工作(本地服务需要一些权限)。
我能够通过删除我的大部分代码并逐行重新添加它来缩小范围,直到我偶然发现这一点。
我猜这与具有类型属性的接口有关enum
。投射position
为 IPosition 也不起作用。
该接口也是从另一个模块(父应用程序模块)导入的
import { Position } from '../../src/app/models/position';
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import { UserRecord } from 'firebase-functions/lib/providers/auth';
admin.initializeApp();
const promisePool = require('es6-promise-pool');
const PromisePool = promisePool.PromisePool;
// const secureCompare = require('secure-compare');
const MAX_CONCURRENT = 3;
const store = admin.firestore();
exports.updateMetrics = functions.https.onRequest((req, res) => {
// const key = req.query.key;
// // Exit if the keys don't match.
// if (!secureCompare(key, functions.config().cron.key)) {
// console.log(
// 'The key provided in the request does not match the key set in the environment. Check that',
// key,
// 'matches the cron.key attribute in `firebase env:get`'
// );
// res
// .status(403)
// .send(
// 'Security key does not match. Make sure your "key" URL query parameter matches the ' +
// 'cron.key environment variable.'
// );
// return null;
// }
// Fetch all user.
return getUsers()
.then(users => {
// Use a pool so that we delete maximum `MAX_CONCURRENT` users in parallel.
const pool = new PromisePool(
() => runMetricsAnalysis(users),
MAX_CONCURRENT
);
return pool.start();
})
.then(() => {
console.log('metrics updated');
res.send('metrics updated');
return null;
});
});
/**
* Returns the list of all users.
*/
function getUsers(users: UserRecord[] = [], nextPageToken?: string) {
let tempUsers: UserRecord[] = users;
return admin
.auth()
.listUsers(1000, nextPageToken)
.then(result => {
// Concat with list of previously found users if there was more than 1000 users.
tempUsers = tempUsers.concat(result.users);
// If there are more users to fetch we fetch them.
if (result.pageToken) {
return getUsers(tempUsers, result.pageToken);
}
return tempUsers;
});
}
function runMetricsAnalysis(users: UserRecord[]) {
if (users.length > 0) {
const user = users.pop();
if (user != null) {
return getPositions(user)
.then(positions => {
const metrics = generateMetrics(positions);
console.log('metrics', metrics);
return null;
// return writeMetrics(user.uid, metrics).catch(function(err) {
// console.error(err);
// return null;
// });
})
.catch(function(err) {
console.error(err);
return null;
});
}
return null;
}
return null;
}
/**
* Returns the list of positions for the previous month.
*/
function getPositions(user: UserRecord) {
return store
.collection(`users/${user.uid}/positions`)
.orderBy('postedDate', 'desc')
.get()
.then(querySnapshot => querySnapshot.docs.map(doc => doc.data()));
}
interface IMetrics {
portfolioValue: number;
profitLoss: number;
fees: number;
}
/**
* Generate metrics from positions
*/
function generateMetrics(positions: Array<any>): IMetrics {
let portfolioValue = 0;
let profitLoss = 0;
let fees = 0;
if (positions.length > 0) {
console.log('positions 5', positions);
positions
.map(position => new Position(position))
.map(position => {
portfolioValue += position.positionValue;
profitLoss += position.profitLossClosedQuantity;
fees += position.fees;
});
}
const IMetric = {
portfolioValue: portfolioValue,
profitLoss: profitLoss,
fees: fees
};
return IMetric;
}
位置
export interface IPosition {
...
}
export class Position implements IPosition {
...
constructor(position: IPosition) {
...
}
}
更新:
由于某种原因,我以前无法看到错误(可能是因为它只是部署了一个有效的函数的缓存版本。
Here is the error:
Error: Error occurred while parsing your function triggers.
TypeError: Cannot read property 'Timestamp' of undefined
at Object.<anonymous> (/Users/AceGreen/Library/Mobile Documents/com~apple~CloudDocs/Dev/Web/TradingTracker/functions/lib/src/app/models/position.js:5:33)
at Module._compile (internal/modules/cjs/loader.js:736:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:747:10)
at Module.load (internal/modules/cjs/loader.js:628:32)
at tryModuleLoad (internal/modules/cjs/loader.js:568:12)
at Function.Module._load (internal/modules/cjs/loader.js:560:3)
at Module.require (internal/modules/cjs/loader.js:665:17)
at require (internal/modules/cjs/helpers.js:20:18)
at Object.<anonymous> (/Users/AceGreen/Library/Mobile Documents/com~apple~CloudDocs/Dev/Web/TradingTracker/functions/lib/index.js:3:20)
at Module._compile (internal/modules/cjs/loader.js:736:30)
position.js 翻译
const app_1 = require("firebase/app");
var Timestamp = app_1.firestore.Timestamp;
解决方案
我能够解决这个问题。问题似乎是我如何导入时间戳。
const app_1 = require("firebase/app");
var Timestamp = app_1.firestore.Timestamp;
正确方法:
const app_1 = require("firebase");
var Timestamp = app_1.firestore.Timestamp;
重要的提示:
如果 firebase deploy --only 函数无法解析当前函数,它似乎会使用函数的缓存版本。我这样说是因为
lint
当我在函数中引用 Timestamp 时运行不会导致错误,并且看起来部署成功了。由于我已经部署了相同的功能,它似乎使用了缓存版本。我只有在切换计算机并且必须重新安装 firebase-cli 并重新部署时才能发现问题,然后它指出了对时间戳的错误引用。
推荐阅读
- sql-server - SQL Server 未显示列规范
- flutter - Dart - 如何用 copywith 重构这个循环?
- android - 使用 Glide 加载 Firebase 图像的问题
- php - 作曲家因信号 9 失败
- java - 使用 contentType application/json 而不是 application/json-patch+json 的 PATCH
- html - 在 Fabric.JS 画布中更改 IText 颜色(使用 React + typescript)
- dataframe - 加入多个导致广播超时的 pyspark 数据帧
- react-native - 使用烧瓶安全性在登录时将 JWT 添加到 cookie
- python - 使用多索引访问数据帧,日期间歇性失败
- python - 在 InputStream 中,blocksize 有什么作用?(声音设备)