Как записать данные в облако Firestore, используя функции облака - PullRequest
0 голосов
/ 07 ноября 2019

Для приложения по планированию, которое я создаю во Flutter, я пытаюсь записать данные в свою облачную базу данных Firestore с облачными функциями и заданиями cron, чтобы сделать мое приложение более самостоятельным. Я застрял на первом этапе, который пытается заставить мою облачную функцию записывать данные в мою облачную базу данных Firestore.

Ниже я включил ссылки на рисунки на github о том, как мои текущие данные структурированы в Firestore. Я хочу добавить именованные документы в коллекцию 'days' с вложенной коллекцией 'hours', в которой есть больше именованных документов с полями 'hour' и 'reserved'.

Рисунок 1: https://github.com/winckles/rooster/blob/master/Schermafbeelding%202019-11-07%20om%2014.27.55.png?raw=true

Рисунок 2: https://github.com/winckles/rooster/blob/master/Schermafbeelding%202019-11-07%20om%2014.28.26.png?raw=true

Ниже я также включил мою попытку получения данных в Firestore.

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

// admin.firestore().collection('days').add({original: original}). then(writeResult => {
//
// });

exports.updateData = functions.https.onCall((data, context) => {
    const days = admin.firestore().collection('days');
    return days.doc(data['2019-11-08/hours/001']).set({
        hour: '08:00-09:00',
        reserved: '',
    });
});

В идеале я бы хотел, чтобы облачная функция добавляла 14 документов (например, с 2019-11-06 по 2019-11-19) в коллекцию 'days' одновременно. Каждый из этих документов затем будет иметь подколлекцию «часы» с данными из второго снимка экрана (поэтому документы 001, 002, 003 и т. Д. С полями «час» и «зарезервировано»).

Я прочитал документацию по облачным функциями чаще всего обнаруживаются триггеры, когда данные записываются в Firestore, но это не то, что я хочу. Я также попробовал примеры функций быстрого запуска, но безуспешно. Это не должно быть слишком сложно, но я не могу понять это. Я использую Javascript для написания облачной функции. Любая помощь / советы будут с благодарностью!

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

если вы хотите использовать cron в firebase, возможно, будет лучше, если вы используете Google Cloud Scheduler, но будьте осторожны, у этого подхода есть другой тип фактурирования

    exports.scheduledFunction = functions.pubsub.schedule('every 5 minutes').onRun((context) => {
  console.log('This will be run every 5 minutes!');
  return null;
});

Подробнее об этом вы можете узнать в:

https://firebase.google.com/docs/functions/schedule-functions

0 голосов
/ 07 ноября 2019

Вы не указали, что именно не работает для вас. Однако первое, что я заметил, это то, что вы не правильно вызываете initilizeApp из контекста облачных функций. Для облачных функций вам не нужны никакие параметры, поскольку учетные данные по умолчанию должны работать для вас (если вы уже не сделали что-то очень необычное).

Вот облачная функция, которая будет моделировать желаемое поведение. Он не работает в полной мере, так как я обнаружил, что написание кода обработки даты, скорее всего, отвлечет вас от основной части проблемы, о которой вы спрашиваете, а именно от самого пожарного хранилища и кода функций. использует функцию https (поскольку мне немного проще тестировать :), чтобы использовать вызываемую функцию (или любой другой тип функции, например, запланированную функцию, если вы используете задание cron), вам необходимо немного ее отрегулировать. (например, для вызываемой функции вам нужно изменить объявление обратно на onCall и изменить последний вызов .then() для возврата значения, которое вы хотите вернуть).

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

const db = admin.firestore();

exports.doIt = functions.https.onRequest((request, response) => {
    const days = db.collection('days');
    const writePromises = [];

    ['2019-11-08', '2019-11-09'].forEach((day) => {
      const documentReference = days.doc(day);
      writePromises.push(documentReference.set({reserved: ''}));

      const hoursReference = documentReference.collection('hours');
      const dataMap = { '001': '08:00-09:00',
                        '002': '09:00-10:00',
                        '003': '10:00-11:00',
                        '004': '11:00-12:00' };
      Object.keys(dataMap).forEach((hour) => {
        writePromises.push(hoursReference.doc(hour).set({
          hour: dataMap[hour],
          reserved: ''
        }))
      });
    });

    return Promise.all(writePromises)
      .then(() => { response.send('ok'); })
      .catch((err) => { console.log(err); });
  });

Обратите внимание, что когда вынаписать всю эту структуру, вам будет выставлен счет за запись в каждый документ. На самом деле не существует способа избежать этого, так как записи оплачиваются за документ, а не за запрос.

Аналогично, вы можете рассмотреть возможность сделать это как пакетная запись -Приведенный выше пример просто показывает базовый подход к написанию. Пакетная запись помещает все документы в базу данных атомарно. Тем не менее, пакетная запись ограничена 500 обновлениями, которые вы получите примерно за 21 день данных (21 день * 24 часа). Это выглядело бы очень похоже на вышеприведенное (ниже приводится только содержимое самой функции:

    const days = db.collection('days');
    const batch = db.batch();

    ['2019-11-08', '2019-11-09'].forEach((day) => {
      const documentReference = days.doc(day);
      batch.set(documentReference, {reserved: ''});

      const hoursReference = documentReference.collection('hours');
      const dataMap = { '001': '08:00-09:00',
                        '002': '09:00-10:00',
                        '003': '10:00-11:00',
                        '004': '11:00-12:00' };
      Object.keys(dataMap).forEach((hour) => {
        batch.set(hoursReference.doc(hour), {
          hour: dataMap[hour],
          reserved: ''
        });
      });
    });

    return batch.commit()
      .then(() => { response.send('ok'); })
      .catch((err) => { console.log(err); });

Я немного удивляюсь, почему вам нужно сделать это в облачной функции, а не черезПозвоните в Firestore прямо из вашего приложения. Несмотря на это, приведенное выше должно позволить вам начать работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...