Функции Firebase возвращают RangeError в Function.MapValues

У меня возникла проблема с функцией firebase, написанной на TypeScript для среды Node.js. У меня есть функция с https-endpoint, где клиент может отправлять данные, которые необходимо сохранить в базе данных. Чтобы узнать, какие объекты уже были добавлены в базу данных, он сначала считывает путь ("уважать"), который имеет упрощенный реестр объекта (lookup/:objectId/true). Затем он создает значения, которые должны быть обновлены по фактическому пути к объекту, и обновляет их в базе данных.

Функция следующая:

export const scrapeAssignments = functions.https.onCall((data, context) => {
    const htmlString = data.htmlString
    // const htmlString = fs.readFileSync(testPath.join(__dirname, "./assignmentListExample.html"), { encoding: 'utf8' })
    if (!(typeof htmlString === 'string') || htmlString.length === 0) {
        throw new functions.https.HttpsError('invalid-argument', 'The function must be called with one argument "htmlString"');
    }

    const userId = getUserIdFromCallableContext(context)
    console.info("userId", userId)
    let newAssignments: ScrapedAssignment[] = []
    try {
        newAssignments = parseAssignment(htmlString)
    } catch (e) {
        const error = <Error>e
        throw new functions.https.HttpsError('not-found', 'parsing error: ' + error.message)
    }

    return admin.database().ref("lookup").child(userId).child("assignments")
        .once("value", lookupSnapshot => {
            const oldAssignmentsLookup = lookupSnapshot.val() || {}
            const newAssignmentsLookup = makeLookup(newAssignments)

            // 1. Create update values for scraped assignment data
            let scrapedAssignmentUpdateValues = newAssignments.reduce((prev, current) => {
                const prefixed = prefixObject(current.id + "/", current)
                return { ...prev, ...prefixed }
            }, {})

            // 2. Use the diff from the two lookups to find old assignments to delete
            const removeAssignmentsValues = {}
            Object.keys(oldAssignmentsLookup).forEach(assignmentId => {
                if (isUndefined(newAssignmentsLookup[assignmentId]))
                    removeAssignmentsValues[assignmentId] = null
            })

            // 3. Add other user values to newly found assignments
            Object.keys(newAssignmentsLookup).forEach(assignmentId => {
                if (isUndefined(oldAssignmentsLookup[assignmentId])) {
                    const doneKey = assignmentId + "/done" 
                    scrapedAssignmentUpdateValues[doneKey] = false
                }
            })

            const combinedValues = { ...scrapedAssignmentUpdateValues, ...removeAssignmentsValues }
            return admin.database().ref("userAssignments").child(userId).update(combinedValues)
        }).catch(reason => {
            throw new functions.https.HttpsError('internal', 'Database reason: ' + reason)
        })
})

Я вижу, что данные записываются в нужное место, и все, кажется, идет так, как ожидалось, за исключением того, что когда я вызываю функцию из приложения iOS, она возвращает ошибку "Внутренний"

Когда я проверяю журналы функций в облачной консоли, я вижу следующую ошибку:

assignment-scrapeAssignments uolk47opctna Unhandled error RangeError: Maximum call stack size exceeded at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13395:23) at encode (/user_code/node_modules/firebase-functions/lib/providers/https.js:204:18) at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13400:38 at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:4925:15 at baseForOwn (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:3010:24) at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13399:7) at encode (/user_code/node_modules/firebase-functions/lib/providers/https.js:204:18) at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13400:38 at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:4925:15 at baseForOwn (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:3010:24) at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13399:7)

Все, что я могу прочитать, это то, что это ошибка «RangeError: превышен максимальный размер стека вызовов», и что-то происходит на Function.mapValues. Как я могу прочитать из этот ТАК вопрос, похоже, проблема с чтением и записью в одно и то же место в одно и то же время. Но я совершенно уверен, что здесь я этим не занимаюсь .. Плюс все вроде ведет себя так, как должно, за исключением самой ошибки.

Когда combinedValues обновляется, это объект с ~ 300 парами ключ / значение, это проблема?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
240
1

Ответы 1

Похоже, вашей функции не хватает памяти, каждая облачная функция выделила память для своего выполнения. Вы можете попробовать увеличить размер стека со значения по умолчанию (256 МБ) до 2 ГБ, перейдя по ссылке: Функции-> Панель управления, затем перейдите к проблемной функции и щелкните в правом меню «Подробная статистика использования»:

затем в сведениях о вашей функции на панели управления облаком Google нажмите редактировать:

затем увеличьте значение «выделенной памяти» до 2 ГБ (или ниже достаточного значения):

примечание: вы должны иметь в виду, что при росте объема данных вы можете превысить наивысший предел, поэтому учитывайте это при запросе в облачных функциях.

Другие вопросы по теме