我在firebase云功能中遇到了一些问题。我正在尝试做的是获取文档,从中提取文本并在该文本中搜索某些搜索词。
我遇到的问题是承诺。
编辑:我已经附加了我正在使用的当前代码,我已经放弃使用子函数来分解代码,现在这一切都在一个大块中。
这应该有助于调试。
当尝试在第93行检索搜索模式时,它当前会卡住。这是在执行此点之后停止代码,但是我不知道为什么这个firestore查询不起作用。
我添加了@augustzf提出的修复程序。
import functions = require('firebase-functions');
import admin = require('firebase-admin');
import path = require('path');
import suffixArray from './suffixArray';
interface suffix {
index: number;
rank: Array<any>;
}
interface Location {
lid: string;
location_name: string;
location_type: string;
sentimental_value: number;
}
interface Context {
lid: string;
context_string: string;
fid: string;
}
export const processFile = functions.storage.object().onFinalize(async file => {
const fileBucket = file.bucket;
const filePath = file.name;
console.log(`File path ${filePath}`);
const serviceAccount = require(__dirname + '/../config/serviceAccount.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'someDB'
});
const firestore = admin.firestore();
const settings = { timestampsInSnapshots: true };
firestore.settings(settings);
const fileDet = path.basename(filePath);
const fileNameSplit = fileDet.split('.');
const fileExt = fileNameSplit.pop();
const fileName = fileNameSplit.join('.');
const bucket = admin.storage().bucket(fileBucket);
const fileRef = bucket.file(filePath);
const searchTerms = file.metadata.searchTerms.split(', ');
let _path = '';
console.log('Getting Download URL');
try {
_path = `/tmp/${fileName}.${fileExt}`;
console.log(`Downloading to: ${_path}`);
await fileRef.download({ destination: _path });
console.log('File Saved');
} catch (e) {
console.error(e);
}
console.log(`Getting Details: ${_path}`);
let text: string = '';
switch (fileExt) {
case 'docx':
case 'doc':
const WordExtractor = require('word-extractor');
const extractor = new WordExtractor();
const extracted = await extractor.extract(_path);
text = extracted.getBody();
break;
case 'pdf':
break;
case 'txt':
const textract = require('textract');
textract.fromFileWithPath(_path, function(extractedError, string) {
if (extractedError) {
console.error(extractedError);
}
if (string !== null) {
text = string;
}
});
break;
default:
console.log('Unsupported File Type');
return null;
}
console.log(`Processing: ${fileName}`);
console.log('Creating Suffix Array');
const suffix_array = suffixArray(text);
console.log(`Suffix Array Created: ${suffix_array}`);
console.log('Getting Search Patterns');
let searchPatterns;
try {
searchPatterns = await admin
.firestore()
.collection('FYP_LOCATIONS')
.get();
} catch (error) {
console.error(error);
}
console.log(`Search Patterns Received: ${searchPatterns}`);
const contexts: Array<Context> = [];
console.log('Creating Contexts');
for (const searchPattern of searchPatterns.docs) {
const patternDoc = searchPattern.data();
const pattern: string = patternDoc.location_name.toLowerCase();
console.log(pattern);
console.log(`Beginning search for: ${pattern}`);
let start = 0;
let end = suffix_array.length;
const matchedIndexes: Array<number> = [];
while (start < end) {
const mid: number = (end - 1) / 2;
const index: number = suffix_array[mid];
const finalIndex: number = index + pattern.length;
if (finalIndex <= text.length) {
const substring: string = text.substring(index, finalIndex);
const match: number = pattern.localeCompare(substring);
if (match === 0) {
console.log(`Match Found at Index: ${index}`);
matchedIndexes.push(index);
} else if (match < 0) {
end = mid;
} else if (match > 0) {
start = mid;
}
console.log(matchedIndexes);
}
}
if (matchedIndexes.length === 0) {
console.log(`No matches found for search term: ${pattern}`);
}
for (const index of matchedIndexes) {
let left = index - 25;
let right = index + patternDoc.location_name.length + 25;
if (left < 0) {
left = 0;
}
if (right > text.length) {
right = text.length;
}
const context = text.substring(left, right);
contexts.push({
lid: patternDoc.lid,
context_string: context,
fid: fileName
});
}
}
for (const context of contexts) {
admin
.firestore()
.collection('FYP_CONTEXTS')
.add(context)
.then(contextDoc => {
console.log(`Context Added: ${contextDoc}`);
})
.catch(error => {
console.error(error);
});
}
const data = {
processed: 1
};
return admin
.firestore()
.doc('FYP_FILES/' + fileName)
.update(data);
});
我已经尝试了很多方法来尝试解决这个问题,但没有提出任何建议,我感觉这与我代码中其他现有的承诺有关,但我不确定。
我们将非常感谢您提供的任何帮助。 :)
谢谢,亚历克斯
通常,您应该避免使用forEach和异步方法。这是因为forEach将启动每个异步调用而不保留(并因此等待)返回的promise。
在你的情况下,这似乎是你的方法中的一个问题:
contexts.forEach(async (context: Context) => {
try {
const contextDoc = await admin
.firestore()
.collection('FYP_CONTEXTS')
.add(context);
console.log(`Context Added: ${contextDoc}`);
} catch (error) {
console.error(error);
}
});
这样会更好:
for (const context of contexts) {
try {
const contextDoc = await admin
.firestore()
.collection('FYP_CONTEXTS')
.add(context);
console.log(`Context Added: ${contextDoc}`);
} catch (error) {
console.error(error);
}
}