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

Я хочу добавить фиктивные значения в firestore, используя облачные функции, и я использую триггер http, чтобы передать число фиктивных значений, которые я хочу создать, это не работает

exports.addDummyUsers = functions.https
.onRequest((request,response)=>{

    let dbb=admin.firestore();
    let counter = request.query.counter;

     for(let i=0;i<counter;i++){
        dbb.collection('Users').doc('Lone').set({
            email: 'Dummy',
            name: 'Dummy',
            phoneNumber: 'Dummy'
        });
        console.log("Dummy " + counter + ' added');
     }

    response.send(counter + ' Dummy Values Created!');
});

Ответы [ 2 ]

2 голосов
/ 20 октября 2019

Обновлен ответ после комментария Фрэнка ниже:

Вы хотите создать несколько документов Firestore параллельно. В вашем случае (нет необходимости в атомарной записи) лучше всего использовать Promise.all().

Следует дождаться завершения набора асинхронных операций, прежде чем отправлять ответ, т.е. подождите, пока единственное обещание, возвращенное Promise.all(), разрешится.

Итак, должно работать следующее:

exports.addDummyUsers = functions.https.onRequest((request, response) => {

        let dbb = admin.firestore();
        let counter = request.query.counter;

        const promises = []

        for (let i = 0; i < counter; i++) {
            promises.push(
                dbb.collection('Users').doc('Lone' + i).set({
                    email: 'Dummy',
                    name: 'Dummy',
                    phoneNumber: 'Dummy'
                })
            )
        }

        return Promise.all(promises)
            .then(resultsArray => {
                response.send(counter + ' Dummy Values Created!');
            })
            .catch(error => {

               //Watch the official video: https://www.youtube.com/watch?v=7IkUgCLr5oA&t=1s&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=3

            });

});

Исходный ответ:

См. Комментарий Фрэнка ниже о том, почему лучше использовать Promise.all() в любом случае.

См. Также следующее замечание в doc :«... Пакетные записи работают лучше, чем сериализированные записи , но не лучше, чем параллельные записи .

Вы должны использовать пакетную запись (если у вас естьменее 500 документов для записи) или используйте Promise.all().

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

Поэтому должно работать следующее:

exports.addDummyUsers = functions.https.onRequest((request, response) => {

    let dbb = admin.firestore();
    let counter = request.query.counter;

    if (counter < 500) {
        //Use batched write
        let batch = dbb.batch();

        for (let i = 0; i < counter; i++) {

            const docRef = dbb.collection('Users').doc('Lone' + i);  //Here you need to create different doc reference. E.g. use the value of i
            batch.set(docRef, {
                email: 'Dummy',
                name: 'Dummy',
                phoneNumber: 'Dummy'
            });
        }

        return batch.commit()
            .then(() => {
                response.send(counter + ' Dummy Values Created!');
            })
            .catch(error => {
                //Watch the official video: https://www.youtube.com/watch?v=7IkUgCLr5oA&t=1s&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=3
            });


    } else {
        //Use Promise.all
        const promises = []

        for (let i = 0; i < counter; i++) {
            promises.push(
                dbb.collection('Users').doc('Lone' + i).set({
                    email: 'Dummy',
                    name: 'Dummy',
                    phoneNumber: 'Dummy'
                })
            )
        }

        return Promise.all(promises)
            .then(resultsArray => {
                response.send(counter + ' Dummy Values Created!');
            })
            .catch(error => {

                //Watch the official video

            });

    }

});
1 голос
/ 20 октября 2019

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

const functions = require('firebase-functions');

exports.addDummyUsers = functions.https.onRequest(async (request,response)=>{

let dbb=admin.firestore();
let counter = request.query.counter;
let userName = ""

for(let i=0;i<counter;i++){

    userName = "Lone" + i.toString().padStart(4, '0') // pad to length 4 with leading zeros
    await dbb.collection('Users').doc(userName).set({
        email: 'Dummy',
        name: 'Dummy',
        phoneNumber: 'Dummy'
    });
    console.log("Dummy " + counter + ' added');
 }

response.send(counter + ' Dummy Values Created!');
});

Проблемы в вашем коде следующие:

В строке dbb.collection('Users').doc('Lone').set({

вы не добавляете i в имя документа, поэтому продолжаете перезаписыватьтот же документ "Одинокий". Рено исправил это.

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

exports.addDummyUsers = functions.https.onRequest(async (request,response)=>{

означает, что вы можете использовать await, а это означает, что код будет ждать, пока каждый документ не будет добавлен. это гораздо эффективнее, если вы выполняете пакетную запись, но, как указал Рено, 500 записей (или комбинация операций добавления, обновления или удаления) - это предел.

Вы также можете сделать то же самое, выполнив пакетную запись. внутри цикла, если счетчик больше 500.

Кроме того, чтобы сортировка выглядела более логично в консоли Firebase, я добавил значение счетчика до 4 (очевидно, этого было бы недостаточно, если счетчик был переданкак 10000)

Чтобы изменить время ожидания, выполните следующие действия:

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

const runtimeOpts = {
  timeoutSeconds: 300,
  memory: '1GB'
}

exports.addFirestoreData = functions.wunWith(runtimeOpts).https.onCall(async data => {

Еще одно примечание. Вы должны быть осторожны, чтобы не создавать горячие точки в своих данных, не используя автоматически сгенерированные идентификаторы документов.

Ваши пользователи будут находиться в одной области, так как все имена Lone0001, Lone002 и т. Д., Что будет означать, что доступ будет сильно конфликтовать и, следовательно, снижать производительность.

Точкаавтоматически сгенерированные идентификаторы документов состоят в том, что они разработаны, чтобы избежать горячих точек. Здесь обсуждаются лучшие практики https://cloud.google.com/firestore/docs/best-practices

...