Моя цель — удалить все узлы сообщений через 24 часа после их отправки с помощью облачных функций Firebase и базы данных реального времени. Я попытался скопировать и вставить ответ из эта почта, однако по какой-то причине сообщения удаляются сразу после их создания, а не через 24 часа. Если кто-то может помочь мне решить эту проблему, я был бы очень признателен. Я пробовал несколько разных ответов, основанных на одной и той же проблеме, и они не сработали для меня.
Вот мой файл index.js:
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
// Cut off time. Child nodes older than this will be deleted.
const CUT_OFF_TIME = 24 * 60 * 60 * 1000; // 2 Hours in milliseconds.
exports.deleteOldMessages = functions.database.ref('/Message/{chatRoomId}').onWrite(async (change) => {
const ref = change.after.ref.parent; // reference to the parent
const now = Date.now();
const cutoff = now - CUT_OFF_TIME;
const oldItemsQuery = ref.orderByChild('seconds').endAt(cutoff);
const snapshot = await oldItemsQuery.once('value');
// create a map with all children that need to be removed
const updates = {};
snapshot.forEach(child => {
updates[child.key] = null;
});
// execute all updates in one go and return the result to end the function
return ref.update(updates);
});
@FrankvanPuffelen Извините, что задаю этот вопрос, но что вы подразумеваете под его регистрацией и как? Сохраненные секунды взяты из секунд с 1970 года.
console.info(cutoff)
, а затем проверьте панель ведения журнала ваших облачных функций. Если вы новичок в JavaScript, облачные функции для Firebase — не лучший способ его изучить. Я рекомендую сначала прочитать Документация Firebase для веб-разработчиков. Это охватывает многие основные взаимодействия JavaScript и базы данных Firebase. Вы также можете использовать Admin SDK в локальном процессе Node.js, который можно отлаживать с помощью локального отладчика. После этого вы будете намного лучше подготовлены к написанию кода для облачных функций.
@FrankvanPuffelen Прошу прощения за поздний ответ. Я зарегистрировался и получил 1559331549417 в консоли. Что я должен делать дальше? Я ценю вашу помощь в этом
1559331549417
выглядит позже, чем любые ценности, которыми вы с нами поделились. По существу: сравните зарегистрированное значение со значениями в вашей базе данных и посмотрите, действительно ли они все старше этого. Если да, то проблема в том, как вы определяете значение cutoff
.
@FrankvanPuffelen Я только что попытался отправить еще одно сообщение и сравнить время. Время в базе данных — 1559426062, а время для зарегистрированного значения — 1559339672823. Может ли быть так, что время отсечки делает это в миллисекундах или что-то в этом роде? Время в базе данных находится в Date().timeIntervalSince1970 в Swift.
Это действительно похоже на то, что вы сохраняете время от клиента в секундах, что довольно часто встречается в iOS. Смотрите мой ответ здесь: stackoverflow.com/questions/52600881/…
Я хочу удалять узлы после окончания дня, независимо от того, когда они были созданы. Как к этому подступиться?
@DheerajMahra, возможно, вы захотите изучить облачный планировщик. Это то, что я в конце концов сделал для своей цели, но я думаю, что вы могли бы сделать то же самое для себя.
Облачный планировщик @Jaqueline входит в план blaze. :(
@DheerajMahra да, но вы все еще получаете план искры, чтобы использовать бесплатный лимит. Вы также можете установить лимит платежа.
@Жаклин Нис. Позвольте мне изучить планы.
В комментариях вы указали, что используете Swift. Из этого и снимка экрана видно, что вы храните метку времени в секундах с 1970 года, в то время как код в ваших облачных функциях предполагает, что она указана в миллисекундах.
Самое простое исправление:
// Cut off time. Child nodes older than this will be deleted.
const CUT_OFF_TIME = 24 * 60 * 60 * 1000; // 2 Hours in milliseconds.
exports.deleteOldMessages = functions.database.ref('/Message/{chatRoomId}').onWrite(async (change) => {
const ref = change.after.ref.parent; // reference to the parent
const now = Date.now();
const cutoff = (now - CUT_OFF_TIME) / 1000; // convert to seconds
const oldItemsQuery = ref.orderByChild('seconds').endAt(cutoff);
const snapshot = await oldItemsQuery.once('value');
// create a map with all children that need to be removed
const updates = {};
snapshot.forEach(child => {
updates[child.key] = null;
});
// execute all updates in one go and return the result to end the function
return ref.update(updates);
});
Также см. мой ответ здесь: Как удалить дочерний узел после того, как определенная дата будет передана в облачных функциях Firebase?
Я пытался сделать это, и я все еще получаю тот же ответ, что и раньше, я не понимаю. Я также посмотрел на другой ответ, но функция выполняется в HTTP, а не в onWrite
То, как запускается функция, не должно иметь большого значения, пока вы подключаетесь ref
. Если это все еще не работает, сделайте то же самое, что и раньше: зарегистрируйте cutoff
и сравните его со значениями в вашей базе данных.
Я пробовал все это, но по какой-то причине я все еще получаю тот же результат. Я также пытался сделать секунды в моей базе данных миллисекундами и использовать исходную функцию, и они все равно удаляются сразу. Есть ли у вас какие-либо предложения о том, как я могу это сделать? Это прямо на грани работы, я чувствую, что его просто нужно немного изменить. Значения в журнале остались прежними.
Проблема в вашем исходном коде заключалась в сравнении секунд и миллисекунд, о которых я ответил. Если вы зарегистрируете значение cutoff
, вы увидите, с чем вы сравниваете значение seconds
в базе данных. Если вы сообщите нам, что он регистрирует, мы можем помочь с этим.
Секунды, хранящиеся в базе данных, составляют 1560021980, а журнал отсечки — 1560021905247. Большое вам спасибо за помощь, я очень ценю это!
Ах, теперь я наконец вижу то, что забыл показать в своем ответе. Проверьте обновленный код. Я настоятельно рекомендую потратить некоторое время на изучение JavaScript с помощью учебника, так как попытка модифицировать облачные функции, как это, определенно не самый простой способ его изучения.
Я определенно согласен! Я только что наткнулся на облачные функции и нашел, что они идеально подходят для того, что я пытаюсь сделать, а не пытаюсь сделать это на стороне пользователя. Это очень странно, я получаю те же результаты. Примерно через 2 секунды удаление занимает больше времени, но сообщения все равно удаляются сразу. Может ли это быть другим фактором? Вот журнал 1560043238.927 и вот значение базы данных 1560043316
у вас есть предложение, что я могу сделать?
Многие разработчики сообщали о проблемах с реализацией этого, но, как и в случае с здесь на прошлой неделе, проблема всегда заключалась в вносимом ими изменении. Например: каково значение
cutoff
, когда вы его регистрируете? Как это соотносится со значениемseconds
в вашем JSON?