【发布时间】:2018-03-11 11:47:52
【问题描述】:
我是 Firebase 的新手,正在测试我最近部署的 Google ML Engine 模型。我试图按照这个 repo 的说明进行操作:https://github.com/sararob/tswift-detection 并且能够按照建议部署 firebase 解决方案。但是当我在 Firebase 上运行该功能时(我将图像上传到 Firebase 存储中的图像文件夹),我收到一条错误消息:
Error occurred: TypeError: Cannot read property 'getApplicationDefault' of undefined
at Promise (/user_code/index.js:24:20)
at cmlePredict (/user_code/index.js:23:12)
at file.download.then.then.then (/user_code/index.js:110:20)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
这里是firebase函数供参考:
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
// response.send("Hello from Firebase!");
// });
'use strict';
const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage');
const admin = require('firebase-admin');
const exec = require('child_process').exec;
const path = require('path');
const fs = require('fs');
const google = require('googleapis');
const sizeOf = require('image-size');
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
function cmlePredict(b64img) {
return new Promise((resolve, reject) => {
google.auth.getApplicationDefault(function (err, authClient) {
if (err) {
reject(err);
}
if (authClient.createScopedRequired && authClient.createScopedRequired()) {
authClient = authClient.createScoped([
'https://www.googleapis.com/auth/cloud-platform'
]);
}
var ml = google.ml({
version: 'v1'
});
const params = {
auth: authClient,
name: 'projects/xx/models/xx',
resource: {
instances: [
{
"inputs": {
"b64": b64img
}
}
]
}
};
ml.projects.predict(params, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
});
}
function resizeImg(filepath) {
return new Promise((resolve, reject) => {
exec(`convert ${filepath} -resize 600x ${filepath}`, (err) => {
if (err) {
console.error('Failed to resize image', err);
reject(err);
} else {
console.log('resized image successfully');
resolve(filepath);
}
});
});
}
exports.runPrediction = functions.storage.object().onChange((event) => {
fs.rmdir('./tmp/', (err) => {
if (err) {
console.log('error deleting tmp/ dir');
}
});
const object = event.data;
const fileBucket = object.bucket;
const filePath = object.name;
const bucket = gcs().bucket(fileBucket);
const fileName = path.basename(filePath);
const file = bucket.file(filePath);
if (filePath.startsWith('images/')) {
const destination = '/tmp/' + fileName;
console.log('got a new image', filePath);
return file.download({
destination: destination
}).then(() => {
if(sizeOf(destination).width > 600) {
console.log('scaling image down...');
return resizeImg(destination);
} else {
return destination;
}
}).then(() => {
console.log('base64 encoding image...');
let bitmap = fs.readFileSync(destination);
return new Buffer(bitmap).toString('base64');
}).then((b64string) => {
console.log('sending image to CMLE...');
return cmlePredict(b64string);
}).then((result) => {
let boxes = result.predictions[0].detection_boxes;
let scores = result.predictions[0].detection_scores;
console.log('got prediction with confidence: ',scores[0]);
// Only output predictions with confidence > 70%
if (scores[0] >= 0.7) {
let dimensions = sizeOf(destination);
let box = boxes[0];
let x0 = box[1] * dimensions.width;
let y0 = box[0] * dimensions.height;
let x1 = box[3] * dimensions.width;
let y1 = box[2] * dimensions.height;
// Draw a box on the image around the predicted bounding box
return new Promise((resolve, reject) => {
console.log(destination);
exec(`convert ${destination} -stroke "#39ff14" -strokewidth 10 -fill none -draw "rectangle ${x0},${y0},${x1},${y1}" ${destination}`, (err) => {
if (err) {
console.error('Failed to draw rect.', err);
reject(err);
} else {
console.log('drew the rect');
bucket.upload(destination, {destination: 'test2.jpg'})
resolve(scores[0]);
}
});
});
} else {
return scores[0];
}
})
.then((confidence) => {
let outlinedImgPath = '';
let imageRef = db.collection('predicted_images').doc(filePath.slice(7));
if (confidence > 0.7) {
outlinedImgPath = `outlined_img/${filePath.slice(7)}`;
imageRef.set({
image_path: outlinedImgPath,
confidence: confidence
});
return bucket.upload(destination, {destination: outlinedImgPath});
} else {
imageRef.set({
image_path: outlinedImgPath,
confidence: confidence
});
console.log('No tswift found');
return confidence;
}
})
.catch(err => {
console.log('Error occurred: ',err);
});
} else {
return 'not a new image';
}
});
这些是我正在使用的库:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase experimental:functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"dependencies": {
"firebase-admin": "5.8.1",
"firebase-functions": "0.8.1",
"googleapis": "^27.0.0",
"image-size": "^0.6.1",
"@google-cloud/storage": "^1.5.1"
},
"devDependencies": {
"eslint": "^4.12.0",
"eslint-plugin-promise": "^3.6.0"
},
"private": true
}
在部署时,我收到了以下警告:
24:43 warning Unexpected function expression prefer-arrow-callback
【问题讨论】:
标签: firebase firebase-realtime-database google-compute-engine google-cloud-functions google-cloud-ml