【问题标题】:Could not fetch URI when Child Value is Set in Realtime Database from Firebase Function从 Firebase 函数在实时数据库中设置子值时无法获取 URI
【发布时间】:2019-02-03 06:55:41
【问题描述】:

我正在通过 Node.js 中的 Firebase 函数在 Firebase 实时数据库中设置一个值。 Function 将 base64 图像发送到 API,并将 API 返回的数据存储在实时数据库中。我所有的服务帐户都设置为编辑者角色。当我的代码尝试设置该值时,控制台中会显示此错误:

Could not fetch URI /computeMetadata/v1beta1/instance/service-accounts/default/token

at Request._callback (/user_code/node_modules/@google-cloud/storage/node_modules/google-auth-library/lib/transporters.js:100:13)
at Request.self.callback (/user_code/node_modules/@google-cloud/storage/node_modules/google-auth-library/node_modules/request/request.js:187:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/user_code/node_modules/@google-cloud/storage/node_modules/google-auth-library/node_modules/request/request.js:1044:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at IncomingMessage.<anonymous> (/user_code/node_modules/@google-cloud/storage/node_modules/google-auth-library/node_modules/request/request.js:965:12)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)

我的节点代码是:

const request = require('request-promise');
const gcs = require('@google-cloud/storage')();
const path = require('path');
const os = require('os');
const fs = require('fs');
const firebase = require('firebase');

exports.identifyUpdate = functions.storage.object().onFinalize((object) => {

    const fileBucket = object.bucket;
    const filePath = object.name;
    const contentType = object.contentType;
    const fileName = path.basename(filePath);

    if(!filePath.substring(0,filePath.indexOf('/')) == 'updates') {
        console.log("Triggered by non-update photo")
        return null;
    }

    console.log("Update photo added")

    // Create Firebase app (for Realtime Database access)

    var config = {
        apiKey: "xxxxx",
        authDomain: "xxxxx",
        databaseURL: "xxxxx",
        storageBucket: "xxxxx",
    };

    if(!firebase.apps.length) {
        firebase.initializeApp(config);
    }

    // Trace back to Update stored in Realtime Database

    const database = firebase.database().ref()
    const pendingRef = database.child('pendingUpdates')

    console.log(filePath)

    const splitPath = filePath.split(path.sep)

    const patientID = splitPath[1]
    console.log('Patient ID: ' + patientID)

    const updateID = splitPath[2]
    console.log('Update ID: ' + updateID)

    const updateRef = pendingRef.child(patientID).child(updateID)

    console.log('Found Update reference')

    const photoRef = updateRef.child('photoURLs').child(fileName)

    console.log('Photo Reference: ' + photoRef)

    // Download and convert image to base64

    const bucket = gcs.bucket(fileBucket)
    const tempFilePath = path.join(os.tmpdir(), fileName)
    const metadata = {
        contentType: contentType
    };

    var base64;

    return bucket.file(filePath).download({
        destination: tempFilePath
    }).then(() => {
        console.log('Image downloaded locally to', tempFilePath)
    }).then(() => {

        base64 = base64_encode(tempFilePath)
        console.log("Base 64: " + base64)

    }).then(() => {
    // Send image data to Kairos

        var options = {
            method: 'POST',
            uri: 'https://api.kairos.com/recognize',
            body: {
                'image': base64,
                'gallery_name': 'gallerytest1'
            },
            headers: {
                'app_id': 'xxxxx',
                'app_key': 'xxxxx'
            },
            json: true
        }

        return new Promise (() => {
            console.log(options)
            request(options)
            .then(function(repos) {

                console.log('API call succeeded');

                console.log('Kairos response: ' + repos);

                const apiResult = repos['images']
                console.log("Result \n" + JSON.stringify(apiResult))

                const faceData = face_data(apiResult)

                console.log("face data\n" + JSON.stringify(face_data(apiResult)))

                const photoURL = photoRef.once('value')
                console.log(photoURL)
                updateRef.child('faceData').set({photoURL : faceData})

            }) 
            .catch(function(err) {
                console.log(err)
            })
        });

    })

    // Delete app instance (to prevent concurrency leaks)

    const deleteApp = () => app.delete().catch(() => null);
    deleteApp.call

})

function base64_encode(file) {
    // read binary data
    var bitmap = fs.readFileSync(file);
    // convert binary data to base64 encoded string
    return new Buffer(bitmap).toString('base64');
}

function face_data(response) {

    var faceData = {};

    for(i = 0; i < response.length; i++) {

        const face = response[i]["transaction"];
        const id = face["subject_id"]
        const topLeftX = face["topLeftX"]
        const topLeftY = face["topLeftY"]
        const width = face["width"]
        const height = face["height"]

        faceData[i] = {
            'face_id': id,
            'topLeftX': topLeftX,
            'topLeftY': topLeftY,
            'width': width,
            'height': height
        }

        console.log(faceData[i])        

    }

    return faceData

}  

【问题讨论】:

  • 错误消息中的/computeMetadata/v1beta1/instance/service-accounts/default/token URL 似乎表明获取默认服务帐户的令牌时出现问题。如果那是在 Firebase 中,您可以在不调用 3rd 方 API 的情况下重现它吗?虽然这不能解决问题,但有助于将其隔离到更小的代码部分。
  • 我试过这样做,但错误仍然存​​在。我怀疑问题出在 updateRef.child('faceData').set({photoURL : faceData}) 和与之相关的服务帐户上。

标签: node.js firebase firebase-realtime-database google-cloud-functions


【解决方案1】:

您是否使用付费计划(Flame 或 Blaze)?如果不是,您将无法从 Cloud Function 调用外部服务。

请参阅 https://firebase.google.com/pricing/,其中解释说“Spark 计划仅允许向 Google 拥有的服务发出出站网络请求”(您必须将鼠标悬停在靠近“云功能”标题的问号上)。

【讨论】:

  • 我正在使用 Flame 计划,来自 API 的响应正在返回并且打印正常。我确实对设置数据库值的相同代码的权限有问题,所以我认为这可能与此有关。
猜你喜欢
  • 2019-09-30
  • 2020-02-27
  • 1970-01-01
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多