如何使此Firebase onUpdate函数起作用?

时间:2019-05-27 14:50:29

标签: javascript firebase firebase-realtime-database google-cloud-functions

大家好,我正在制作一个应用程序,并且使用Firebase作为数据库,身份验证服务器和图像存储,因为我要在其上存储图像,所以我必须在服务器端编写一些代码。

这是我已经编写的代码:

const functions = require('firebase-functions');
const cors = require('cors')({ origin: true });
const Busboy = require('busboy');
const os = require('os');
const path = require('path');
const fs = require('fs');
const fbAdmin = require('firebase-admin');
const uuid = require('uuid/v4');

// // 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!");
// });
const gcconfig = {
    projectId: 'my-project-id',
    keyFilename: 'myprojectkeyfile.json'
};

const gcs = require('@google-cloud/storage')(gcconfig);

fbAdmin.initializeApp({ credential: 
fbAdmin.credential.cert(require('./myprojectkeyfile.json')) });

exports.storeImage = functions.https.onRequest((req, res) => {
    return cors(req, res, () => {
        if (req.method !== 'POST') {
            return res.status(500).json({ message: 'Not allowed.' });
    }

    if (!req.headers.authorization || 
        !req.headers.authorization.startsWith('Bearer ')) {
            return res.status(401).json({ error: 'Unauthorized.' });
    }

    let idToken;
    idToken = req.headers.authorization.split('Bearer ')[1];

    const busboy = new Busboy({ headers: req.headers });
    let uploadData;
    let oldImagePath;

    busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
        const filePath = path.join(os.tmpdir(), filename);
        uploadData = { filePath: filePath, type: mimetype, name: filename };
        file.pipe(fs.createWriteStream(filePath));
    });

    busboy.on('field', (fieldname, value) => {
        oldImagePath = decodeURIComponent(value);
    })

    busboy.on('finish', () => {
        const bucket = gcs.bucket('my-project-id.appspot.com');
        const id = uuid();
        let imagePath = 'images/' + id + '-' + uploadData.name
        if (oldImagePath) {
            imagePath = oldImagePath;
        }

        return fbAdmin.auth().verifyIdToken(idToken).then(decodedToken => {
            return bucket.upload(uploadData.filePath, {
                uploadType: 'media',
                destination: imagePath,
                metadata: {
                    metadata: {
                        contentType: uploadData.type,
                        firebaseStorageDownloadTokens: id
                    }
                }
            });
        })
            .then(() => {
                return res.status(201).json({
                    imageUrl: 'https://firebasestorage.googleapis.com/v0/b/' + bucket.name + '/o/' + 
                        encodeURIComponent(imagePath) + '?alt=media&token=' + id,
                    imagePath: imagePath
                });
            })
            .catch(error => {
                return res.status(401).json({ error: 'Unauthorized!' });
            });
    });
    return busboy.end(req.rawBody);
});
});

exports.deleteImage = 
functions.database.ref('/products/{productId}').onDelete(snapshot => {
    const imageData = snapshot.val();
    const imagePath = imageData.imagePath;

    const bucket = gcs.bucket('my-project-id.appspot.com')
    return bucket.file(imagePath).delete();
});

现在,此代码可以正常工作,除了一件事:如果我在应用程序上更新图像,服务器必须用新图像替换上载的旧图像,但这不会发生,而是服务器将始终添加图像取代旧的。

因此,我想解决此问题,添加一个更新数据库中的内容时触发的函数;因此,当我这样做时,服务器必须添加新图像,还要搜索旧图像并将其删除。 我正在尝试编写该代码,但是由于我不太了解javascript(这是我一生中用javascript写的所有代码),因此可以确定我犯了一些错误,这就是我写的内容:

exports.deleteOnUpdateImage = functions.database.ref('/products/{productId}').onUpdate(snapshot => {
    const oldData = snapshot.before.val();
    const newData = snapshot.after.val();
    const oldImagePath = oldData.imagePath;
    const oldImageUrl = oldData.imageUrl;
    const newImageUrl = newData.imageUrl;

    const bucket = gcs.bucket('my-project-id.appspot.com')

    if (oldImageUrl != newImageUrl) {
         return bucket.file(oldImagePath).delete();
    }
})

您能告诉我如何解决并使其正常工作吗?

如果我的英语不够完美,如果您需要其他详细信息,请告诉我,我非常抱歉!

谢谢!

0 个答案:

没有答案