Я пытаюсь получить все документы в коллекции Firestore, где мое поле referredBy равно переменной refCode (реферальный код). Я продолжаю получать ошибку в Stackdriver: «Ошибка: превышен предел памяти. Вызов функции был прерван».
Инструкции для этой функции находятся здесь: https://firebase.google.com/docs/firestore/query-data/get-data#get_multiple_documents_from_a_collection
Я попытался увеличить выделение памяти для этой облачной функции до 2 ГБ (макс.), Но все равно возникла та же ошибка. В этой коллекции только два документа и только один, который соответствует моим критериям «где», так что размер документов в любом случае не должен быть проблемой.
Это из моего index.js:
const express = require('express');
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const app = express();
// Get referred users:
app.get('path/to/myapp', (req, res) => {
var getReferred = require('./getRefUsers');
if (admin.apps.length === 0 ) { admin.initializeApp(functions.config().firebase); }
var db = admin.firestore();
getReferred.getUsersReferred(req, res, db);
});
exports.getReferred = functions.https.onRequest(app);
Что вызывает следующую функцию:
module.exports = {
getUsersReferred: function(req, res, db) {
const { shopName, twitchId } = req.query;
// Get users account to get their referral code:
var docRef = db.collection('stores').doc(shopName).collection('users').doc(twitchId);
docRef.get()
.then((docSnapshot) => {
if (!docSnapshot.exists) {
var msg = 'User ' + twitchId + ' does not exist.';
console.info(msg);
res.json({ 'status': 'error', 'message': msg });
} else {
var referredUsers = [];
// Get all users who were referred by this user
var refCode = docSnapshot.data().referralCode;
console.info('refCode: ' + refCode + ' shop: ' + shopName + ' id: ' + twitchId);
db.collection('stores').doc(shopName).collection('users').where("referredBy", "= = ", refCode)
.get()
.then(function(querySnapshot) {
console.info('Size: ' + querySnapshot.size);
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
console.info(doc.id, " => ", doc.data());
var username = doc.data().username;
var earned = doc.data().earnedreferpoints;
var id = doc.data().twitchId;
if (typeof earned == 'undefined' || earned == 'no') {
earned = 'No';
} else {
earned = 'Yes';
}
if (doc.data().referredBy == refCode) {
referredUsers[id] = [username, earned];
}
});
// After assembling json object, send to user:
res.json({ 'status': 'success', 'data': referredUsers} );
})
.catch(function(error) {
var msg = 'Error getting users you have referred. Please contact us.';
console.info(msg + ' ', error);
res.json({ 'status': 'error', 'message': msg });
});
}
})
.catch(function(error) {
var msg = '';
console.info(msg);
res.json({ 'status': 'error', 'message': msg });
});
}
};
Код никогда не достигает блока .then(). console.info('Size: ' + querySnapshot.size); не печатается в журнале Stackdriver.
@DougStevenson Я добавил весь соответствующий код. Это из моего index.js и полная функция того, что я пытаюсь сделать. Спасибо, что посмотрели!
Как вы думаете, сколько пользователей соответствуют запросу? Что, если вы запустите тот же запрос в процессе узла на своем рабочем столе?
Это может быть зацепка firebase.google.com/docs/firestore/quotas Вы следили за своими квотами?
@DougStevenson есть только 1 пользователь, который соответствует запросу, только 2 пользователя во всей базе данных, поскольку я просто тестирую эту функцию. На рабочем столе еще не тестировал, попробую.
@kevincoulibaly Я использую тарифный план Blaze, но, тем не менее, у меня недостаточно бесплатной квоты. Менее 100 в день.
Квота не имеет ничего общего с доступной памятью. Если ваш запрос к базе данных никогда не завершается и всегда завершается из-за нехватки памяти, все свидетельства говорят о том, что ваш запрос возвращает больше документов, чем может поместиться в памяти.
@DougStevenson Я пробовал это на своем локальном компьютере, он работает, как ожидалось. Я поменял res.json s на console.info s. Он распечатывает данные для 1 найденной записи, а затем распечатывает массив referUsers с элементом 1.
Тогда это может быть проблема с тем, что вы передаете в res.json ().
@DougStevenson сразу после того, как я звоню в БД, у меня есть console.info('Size: ' + querySnapshot.size);, который никогда не печатается в журнале, поэтому он ошибается на .get() в БД.
Не знаю, что тебе сказать, извини. Убедитесь, что все ваши библиотеки обновлены. Начните с самого простого примера и постепенно продвигайтесь к чему-то более сложному. Люди все время делают запросы к Firestore, поэтому он не является принципиально нарушенным.





Решено.
Если кто-нибудь знает, что Зачем работает, дайте мне знать.
Итак, моя переменная var referredUsers = []; создается до того, как я обращаюсь к базе данных Firestore. Когда мой запрос находит совпадение, он добавляет такие данные в указанныйUsers: referredUsers[id] = [username, earned];, который обрабатывает referredUsers как словарь / объект, а не как массив. Это отлично работало на моем локальном компьютере, и напечатало referUsers как: [ <274940135 empty items>, [ 'areliven', 'Yes' ] ], что выглядит странно, и я не совсем понимаю. Но почему-то это заставляло меня превышать лимит памяти при работе в облачной функции Firebase.
Как я это исправил
Поменял var referredUsers = []; на var referredUsers = {}; вот и все! Теперь локально он распечатывает { '274940135': [ 'areliven', 'Yes' ] } и отлично работает с облачными функциями Firebase.
Опять же, если бы кто-нибудь мог пролить свет на то, как это могло заставить меня превысить лимит памяти на Firebase, было бы здорово узнать!
Как вы уже выяснили, массивы JavaScript - это особые типы объектов, поэтому вы можете рассматривать их как словарь, даже если это не совсем его использование. В вашем случае, если ваш ключ словаря - '274940135', и вы затем получите размер referredUsers с referredUsers.lenght, вы увидите, что массив сообщает вам, что он имеет длину '274940136', даже если он имеет 1 элемент. Я думаю, что среда выполнения CF резервирует место в памяти для вашего динамического массива элементов '274940136', который, вероятно, превышает предел памяти.
Здесь вы показываете только частичную функцию. Отредактируйте вопрос, который показывает код полный, минимальный, воспроизводящий проблему, чтобы мы могли видеть всю картину.