Есть ли способ удалить объекты из Firebase автоматически? [Дубликат]

Итак, просто чтобы понять это, преимущество интерфейса в том, что я могу отделить вызов метода от любого конкретного класса. Вместо этого создается экземпляр интерфейса, где реализация предоставляется из того класса, который я выбираю, который реализует этот интерфейс. Таким образом, у меня есть много классов, которые имеют сходную, но немного отличающуюся функциональность, а в некоторых случаях (случаи, связанные с намерением интерфейса) не заботятся о том, какой именно объект.

Например, я мог бы интерфейс движения. Метод, который делает что-то «движение», и любой объект (Person, Car, Cat), который реализует интерфейс движения, может быть передан и передан для перемещения. Без метода, каждый из которых знает тип класса.

20
задан carterw485 14 August 2015 в 07:28
поделиться

4 ответа

Firebase не поддерживает запросы с динамическим параметром, например «два часа назад». Он может выполнять запрос для определенного значения, например «после 14 августа 2015 года, 7:27:32 утра».

Это означает, что вы можете запустить фрагмент код периодически, чтобы очистить элементы, которые старше 2 часов в это время :

var ref = firebase.database().ref('/path/to/items/');
var now = Date.now();
var cutoff = now - 2 * 60 * 60 * 1000;
var old = ref.orderByChild('timestamp').endAt(cutoff).limitToLast(1);
var listener = old.on('child_added', function(snapshot) {
    snapshot.ref.remove();
});

Как вы заметите, я использую child_added вместо value и I limitToLast(1). Когда я удаляю каждого дочернего объекта, Firebase запускает child_added для нового «последнего» элемента до тех пор, пока после точки отсечения больше нет элементов.

Обновление: если вы хотите запустить этот код в облачных функциях для Firebase:

exports.deleteOldItems = functions.database.ref('/path/to/items/{pushId}')
.onWrite((change, context) => {
  var ref = change.after.ref.parent; // reference to the items
  var now = Date.now();
  var cutoff = now - 2 * 60 * 60 * 1000;
  var oldItemsQuery = ref.orderByChild('timestamp').endAt(cutoff);
  return oldItemsQuery.once('value', function(snapshot) {
    // create a map with all children that need to be removed
    var updates = {};
    snapshot.forEach(function(child) {
      updates[child.key] = null
    });
    // execute all updates in one go and return the result to end the function
    return ref.update(updates);
  });
});

Эта функция запускается всякий раз, когда данные записываются в /path/to/items, поэтому дочерние узлы будут удаляться только при изменении данных.

Этот код теперь также доступный в functions-samples репо .

27
ответ дан Frank van Puffelen 21 August 2018 в 03:52
поделиться
  • 1
    В вашем примере вы получаете записи, сохраненные 2 часа назад или меньше. Возможно, вы должны использовать endAt вместо startAt. Но все равно спасибо за ваш ответ, это помогло мне – Crema 17 May 2016 в 07:03
  • 2
    Хороший улов! Исправлена. – Frank van Puffelen 17 May 2016 в 09:55
  • 3
    Привет, Франк, я пытаюсь сделать что-то подобное в Swift, но я не могу понять, какой метод вы вызываете в слушателе. Я потратил несколько часов на поиск и попытку, но решил, что пришло время попросить о помощи! – Abhi 16 September 2016 в 07:46
  • 4
    snapshot.ref().remove() в Swift с SDK 3.x будет snapshot.ref.removeValue(). См. Руководство guide и reference . – Frank van Puffelen 16 September 2016 в 16:51
  • 5
    Когда я осуществил это, все данные были удалены через 1 секунду вместо 2 часов. Я скопировал и вставлял именно код, так что я не делаю, что происходит? – Dani Kemper 18 September 2017 в 19:13

Вы можете посмотреть Планирование функций Firebase с помощью заданий Cron . Эта ссылка показывает вам, как планировать облачную функцию Firebase для работы с фиксированной скоростью. В запланированной функции Firebase вы можете использовать другие ответы в этом потоке для запроса старых данных и удаления.

3
ответ дан James Oliver 21 August 2018 в 03:52
поделиться

У меня есть функция запуска с помощью HTTP, которая удаляет узлы, в зависимости от того, когда они были созданы и их срок годности.

Когда я добавляю узел в базу данных, ему нужны два поля: timestamp, чтобы узнать, когда

Затем у меня есть эталонная функция HTTP:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

/**
 * @function HTTP trigger that, when triggered by a request, checks every message of the database to delete the expired ones.
 * @type {HttpsFunction}
 */
exports.removeOldMessages = functions.https.onRequest((req, res) => {
    const timeNow = Date.now();
    const messagesRef = admin.database().ref('/messages');
    messagesRef.once('value', (snapshot) => {
        snapshot.forEach((child) => {
            if ((Number(child.val()['timestamp']) + Number(child.val()['duration'])) <= timeNow) {
                child.ref.set(null);
            }
        });
    });
    return res.status(200).end();
});

Вы можете создать задание cron, которое каждые X минут делает запрос на URL-адрес этой функции: https://cron-job.org/en/

Но я предпочитаю запускать собственный скрипт, который делает запрос каждые 10 секунд:

watch -n10 curl -X GET https://(your-zone)-(your-project-id).cloudfunctions.net/removeOldMessages
0
ответ дан Sergio 21 August 2018 в 03:52
поделиться

В последней версии Firebase API ref () изменен на ref

var ref = new Firebase('https://yours.firebaseio.com/path/to/items/');
var now = Date.now();
var cutoff = now - 2 * 60 * 60 * 1000;
var old = ref.orderByChild('timestamp').endAt(cutoff).limitToLast(1);
var listener = old.on('child_added', function(snapshot) {
    snapshot.ref.remove();
});
6
ответ дан Won Jun Bae 21 August 2018 в 03:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: