谷歌云功能导致 Firestore 文档被清空/删除

时间:2021-02-11 13:58:44

标签: firebase google-cloud-firestore google-cloud-functions

这个问题已经困扰我好几天了,但我似乎无法解决它。当我的云功能更新某个 Firestore 文档时,例如/user/1/contact/2 被快速连续多次调用,目标文档被清空/删除。然而,当只进行一次调用时,它工作得很好。日志、审计日志和调试日志显示该函数像这样Function execution took 8308 ms, finished with status: 'ok' 成功并且不会抛出任何错误。

有谁知道是什么导致了这种情况以及我如何防止这种情况发生?

提前致谢。

编辑 1:

这是我的代码(为了可读性稍微整理了一下):

const language = require('@google-cloud/language');
const client = new language.LanguageServiceClient();
const axios = require('axios')
const Firestore = require('@google-cloud/firestore');
const admin = require('firebase-admin');
const FormData = require("form-data");
admin.initializeApp({
    credential: admin.credential.applicationDefault()
});
const db = admin.firestore();

/**
 * Triggered by a change to a Firestore document.
 *
 * @param {!Object} event Event payload.
 * @param {!Object} context Metadata for the event.
 */
exports.helloFirestore = async (event, context) => {

    if (event.updateMask && Object.keys(event.updateMask).length) {
        console.log(`\nupdateMask:`);
        console.log(JSON.stringify(event.updateMask, null, 2));
    }

    var companyId = context.params.companyId
    var functionId = context.params.functionId
    var vacancyId = context.params.vacancyId

    var functionDoc = db.collection("companies").doc(companyId).collection('functions').doc(functionId).collection('vacancies').doc(vacancyId);
    var publicFunctionDoc = db.collection("companies").doc(companyId).collection('public_functions').doc(functionId).collection('vacancies').doc(vacancyId);


    var job = null;
    var publicJob = null;
    var generalJob = null;
    var company = null;
    var ignoredIds = [];
    var users = [];
    await functionDoc.get().then(function (doc) {

        if (doc.exists) {
            job = doc.data();
            job.id = doc.id;
        }
    });

    await publicFunctionDoc.get().then(function (doc) {

        if (doc.exists) {
            publicJob = doc.data();
            publicJob.id = doc.id;
        }
    });

    await db.collection("companies").doc(companyId).get().then(function (doc) {
        if (doc.exists) {
            company = doc.data();
            company.id = doc.id;
        }
    });

    await db.collection("companies").doc(companyId).collection('functions').doc(functionId).get().then(function (doc) {
        if (doc.exists) {
            generalJob = doc.data();
        }
    });

    await db.collection('users').where('preferences.active', '==', true).where('preferences.locked', '==', false).get().then(function (snapshot) {
        snapshot.forEach(user => {
            users.push({
                ...user.data(),
                id: user.id
            })
        })
    });

    await db.collection('users').where('preferences.active', '==', true).where('preferences.owner', '==', company.id).get().then(function (snapshot) {
        snapshot.forEach(user => {
            users.push({
                ...user.data(),
                id: user.id
            })
        })
    });


    if (job.interacted == undefined || job.interacted == null) {
        job.interacted = [];
    }
    if (job.ignored == undefined || job.ignored == null) {
        job.ignored = [];
    }
    if (generalJob.ignored == undefined || generalJob.ignored == null) {
        generalJob.ignored = [];
    }
    if (company.ignored == undefined || company.ignored == null) {
        company.ignored = [];
    }
    if (company.banned == undefined || company.banned == null) {
        company.banned = [];
    }

    ignoredIds = job.ignored.concat(job.banned, company.ignored, company.banned);

    users = users.filter(user => {
        if (ignoredIds.indexOf(user.id) == -1) {
            return true;
        }
        return false;
    });

    if (job != null && users.length > 0) {
        match(job, users, companyId, functionId, vacancyId, functionDoc, publicJob, company);
    }
};

// Matching v1.0
function match(job, people, companyId, functionId, vacancyId, functionDoc, publicJob, company) {

    if (job.matches == null || job.matches == undefined) {
        job.matches = [];
    }

    if (job.hired == null || job.hired == undefined) {
        job.hired = [];
    }


    people.forEach(user => {
        if (user.matches2 == null || user.matches2 == undefined) {
            user.matches2 = [];
        }

        
        if (user.skills2) {
            if (user.matches == undefined || user.matches == null) {

                user.matches = [];
            }
            if (score > 0) {
                if (user.matches2 == undefined || user.matches2 == null) {
                    user.matches2 = [];
                }
                var result = user.matches2.find(obj => {
                    return obj.job == functionId
                })

                if (result == undefined) {

                    var vacancy = {
                        job: functionId,
                        score: score,
                        data: publicJob,
                        company: company,
                        doc: functionDoc,
                        applied: false,
                        date: new Date()
                    };
                    user.matches2.push(vacancy);

                    saveVacancyForUser(user.id, vacancy);



                    if (user.preferences == null || user.preferences == undefined) {
                        user.preferences = {
                            annonymous: false
                        };
                    }
                    if (user.preferences.annonymous != null && user.preferences.annonymous != undefined) {
                        user.profile.annonymous = user.preferences.annonymous
                    }
                }


                var result = job.matches.find(obj => {
                    return obj.user.id == user.id
                })
                var result2 = job.hired.find(obj => {
                    return obj.user.id == user.id
                })

                if (result == undefined && result2 == undefined) {
                        job.matches.push({
                        user: user,
                        score: score
                    });
                }
            }
            saveUserDoc(user.id, user)
        }
    })
    if (job.matches.length > 0) {
        console.log(job.matches.length);
        var obj = {};

        for (var i = 0, len = job.matches.length; i < len; i++) {
            obj[job.matches[i]['user']['id']] = job.matches[i];
        }

        job.matches = new Array();
        for (var key in obj) {
            job.matches.push(obj[key]);
        }

        saveVacancyData(companyId, functionId, vacancyId, job)
    }


}

function unique(data, key) {
    console.log("key:::::::" + key)
    return [
        ...new Map(
            data.map(x => [key(x), x])
        ).values()
    ]
}

async function saveVacancyForUser(uid, vacancy){
    var userVacancyDoc = db.collection("users").doc(uid).collection('vacancies');
    await userVacancyDoc.add(vacancy).then(function () {
            console.log("Document successfully written! --- uservacancy");
        })
        .catch(function (error) {
            console.error("Error writing document: ", error);
        });
}

async function saveUserDoc(uid, user){
    var userDoc = db.collection("users").doc(uid);
    await userDoc.set(user, {
            merge: true
        }).then(function () {
            console.log("Document successfully written! ---- userDoc");
        })
        .catch(function (error) {
            console.error("Error writing document: ", error);
        });
}


async function saveVacancyData(companyId, functionId, vacancyId, job){
    var functionDoc = db.collection("companies").doc(companyId).collection('functions').doc(functionId).collection('vacancies').doc(vacancyId);
    await functionDoc.set(job, {
            merge: false
        }).then(function () {
            console.log("Document successfully written! --- job");
            console.log("hey")
        })
        .catch(function (error) {
            console.error("Error writing document: ", error);
        });
}

0 个答案:

没有答案