Функция Firebase для чтения и записи в Firestore генерирует ReferenceError: запрос не определен при cors и необработанном отклонении - PullRequest
0 голосов
/ 09 февраля 2020

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

Я провел следующий тест функция:

exports.BookLesson = functions.https.onRequest(async (req, res) => {
    var bookingId = req.query.bookingId;
    var idToken = query.query.idToken;

    if(bookingId === undefined)
    {
        console.log("Using body params");
        bookingId = req.body.bookingId;
        idToken = query.body.idToken;
    }
    console.log("BookingId: " +bookingId);
    console.log("IdToken: "+idToken);...

Однако все параметры всегда неопределены. После некоторого чтения я подумал, что это может быть проблема с CORS, поэтому я попытался настроить перенаправление хостинга, но это не дало никаких результатов.

Затем я попытался добавить CORS в свою функцию, как показано в примерах Firebase, предоставленных на GitHub, однако это просто выдает следующие ошибки: Firebase errors

Я являюсь немного потеряно в том, что попробовать сейчас - документация по функциям, кажется, немного вводит в заблуждение, и ни один из примеров не совмещает чтение и запись из того, что я мог видеть. Любые указатели будут высоко оценены. Извиняюсь за плохой код - я из C ++ фона!

Полная функция:

'use strict';

const functions = require('firebase-functions');
const cors = require('cors')({
    origin: true,
  });
const admin = require('firebase-admin');
admin.initializeApp();

exports.BookLesson = functions.https.onRequest(async (req, res) => {

    return cors(req, res, () => {

        var bookingId = req.query.bookingId;
        var year = req.query.year;
        var week = req.query.week;
        var day = req.query.day;
        var idToken = query.query.idToken;

        if(bookingId === undefined)
        {
            console.log("Using body params");
            bookingId = req.body.bookingId;
            year = req.body.year;
            week = req.body.week;
            day = req.body.day;
            idToken = query.body.idToken;
        }

        console.log("BookingId: " +bookingId + " year: " + year + " week: "+ week + " day: " + day);
        console.log("IdToken: "+idToken);

        admin.auth().verifyIdToken(idToken)
        .then(decodedToken => {

            const user = admin.auth.getUser(decodedToken.uid);
            console.log("Got User");
            var result = CheckUserValid(user);

            if (result.UserValid) {
                return WriteBooking(result.User, bookingId, year, week, day);
            } else {
                console.log("User not validated to book");
                throw new Error("User not validated to book");
            }

        })
        .catch(reason => {
            res.send(reason)
        });

        console.log("Complete");
        // Send back a message that we've succesfully written the message
        res.json({result: "Complete"});
    });
});

function CheckUserValid(user)
{
    if(!user.emailVerified)
    {
        console.log("User email not verified.");
        return {UserValid: false};
    }

    console.log("Checking validated users db: " + user.uid);

    admin.firestore().collection("ValidatedUsers").doc(user.uid).get()
    .then(snapshot => {

        console.log("Validated user db returned");
        if(snapshot.exists)
        {
            console.log("User validated");
            return {UserValid: true, User: user};
        }
        console.log("Snapshot doesnt exist");
        return {UserValid: false};

    }).catch(reason => {
        console.log("Error getting validated user from db");
        res.send(reason)
    });
}

function WriteBooking(user, bookingId, year, week, day)
{
    console.log("Writing booking for user: "+user.uid);

    admin.firestore().collection("Bookings").doc(year).collection("A").doc("W"+week).collection("D").doc("D"+day).collection("B")
    .doc(bookingId).collection("U").doc(user.uid).set({

        Name: user.displayName,
        Status: "Unverified"

    })
    .then(result => {

        console.log("Document written to Bookings");
        return "Complete.";

    }).catch(reason => {
        console.log("Error getting validated user from db");
        res.send(reason);
    });
}

И код вызова (значения проверены и верны при отправке):

var bookLessonFunc = firebase.functions().httpsCallable('BookLesson');
    bookLessonFunc({
        bookingId: bookingId,
        year: year,
        week: week,
        day: day,
        idToken: token
    })
    .then(function(result) {

        var message = result.data.result;
        alert(message);

    }).catch(function(error) {
      // Getting the Error details.
      var code = error.code;
      var message = error.message;
      var details = error.details;
      ProcessError("ERROR BOOKING.",error);
    });

1 Ответ

3 голосов
/ 09 февраля 2020

Вы смешиваете Функции вызываемого облака и Функции облака HTTP .

Делая

exports.BookLesson = functions.https.onRequest(async (req, res) => {...})

, вы определяете функцию облака HTTPS ,

но, выполнив

var bookLessonFunc = firebase.functions().httpsCallable('BookLesson');
    bookLessonFunc({....})
    .then(function(result) {...})

в своем клиенте / клиентском интерфейсе, вы фактически вызовете функцию вызываемого облака.

Вам следует либо изменить свою функцию облака на Вызываемый или вызовите функцию BookLesson HTTPS Cloud с fetch() или Ax ios, например.


Например, следующий код с Ax ios должен сделать свое дело (не проверено). Просто измените значение project-id с вашим собственным идентификатором проекта.

axios.get('https://us-central1-<project-id>.cloudfunctions.net/BookLesson', {
    params: {
        bookingId: bookingId,
        year: year,
        week: week,
        day: day,
        idToken: token
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })

PS: Будьте внимательны, чтобы возвращать ответ только после завершения всех асинхронных операций. Посмотрите 3 видео о "JavaScript Promises" из серии Firebase для получения более подробной информации.

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