Облачная функция Geofirestore с Cors, проблема с обещанием запроса NodeJS - PullRequest
0 голосов
/ 10 января 2020

Вот функция Google Cloud, вызывающая Geofirestore после добавления документа способом Geofirestore https://github.com/geofirestore/geofirestore-js

У меня есть один элемент: я получил {"sendit": {"домен ": {" domain ": null," _ events ": {}," _ eventsCount ": 1," members ": []}}} Однако

Я не могу получить его из запроса когда отправляется res.send ({sendit})

const functions = require("firebase-functions");
const admin = require("firebase-admin");
const GeoFirestore = require("geofirestore").GeoFirestore;
//const firestore = require('firebase/firestore');
const cors = require("cors")({
  origin: true,
  allowedHeaders: [
    "Access-Control-Allow-Origin",
    "Access-Control-Allow-Methods",
    "Content-Type",
    "Origin",
    "X-Requested-With",
    "Accept",
    "Access-Control-Allow-Headers"
  ],
  methods: ["POST", "OPTIONS"]
});
require('firebase/firestore');

//serviceAccount=yourServiceAccountKey.json
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "your_firebaseio_domain"
})

const firestoreRef = admin.firestore();
const geofirestore = new GeoFirestore(firestoreRef);
const geocollection = geofirestore.collection("planner");

exports.chooseCity = functions.https.onRequest((req, res) => {
  // Google Cloud Function res.methods
  res.set("Access-Control-Allow-Headers", "Content-Type");
  res.set("Content-Type", "Application/JSON");
  // CORS-enabled req.methods, res.methods
  return cors(req, res, () => {
    res.set("Access-Control-Allow-Headers", "Content-Type");
    res.set("Content-Type", "Application/JSON");
    var origin = req.get("Origin");
    var allowedOrigins = [
      "https://yourdomain.tld"
    ];
    if (allowedOrigins.indexOf(origin) > -1) {
      // Origin Allowed!!
      res.set("Access-Control-Allow-Origin", origin);
      if (req.method === "OPTIONS") {
        // Method accepted for next request
        res.set("Access-Control-Allow-Methods", "POST");
        //SEND or end # option req.method
        return res.status(200).send({});
      } else {
        // After request req.method === 'OPTIONS'
        if (req.body) {
          const radius = req.body.distance;
          const center = new admin.firestore.GeoPoint(req.body.location[0], req.body.location[1])

          const geoQuery = geocollection.near({ center, radius });
[**** Tried this ****]
          let results = []
// Remove documents when they fall out of the query
geoQuery.on('key_exited', ($key) => {
  const index = results.findIndex((place) => place.$key === $key);
  if (index >= 0) results.splice(index, 1);
});

// As documents come in, add the $key/id to them and push them into our results
geoQuery.on('key_entered', ($key, result) => {
  result.$key = $key;
  results.push(result);
});
          return res.status(200).send({results})

[**** Instead of this ****]
          geoQuery.get()
            .then(value => {
              // All GeoDocument returned by GeoQuery,
              //like the GeoDocument added above
              const sendit = value.docs
          res.status(200).send({sendit})
[**End**]
            })
            .catch(err => res.status(400).send(err))
        } else {
          res.status(200).send("no request body");
        }
      }
    } else {
      //Origin Bad!!
      //SEND or end
      return res.status(400).send("no access for this origin");
    }
  });
});

при добавлении документа, в способ геообеспечения, также используется запрос на добавление

import { GeoFirestore } from "geofirestore";
export const createEvent = event => {
  return (dispatch, getState, { getFirebase, getFirestore }) => {
    const firestore = getFirestore();
    const geoFirestore = new GeoFirestore(firestore);
    const geocollection = geoFirestore.collection("planner");
    geocollection.add({
      name: "Geofirestore",
      score: 100,
      // The coordinates field must be a GeoPoint!
      coordinates: event.geopoint,
      title: event.title,
      body: event.body,
      chosenPhoto: event.chosenPhoto,
      date: event.date,
      createdAt: event.createdAt,
      updatedAt: event.updatedAt,
      address: event.address,
      location: event.location,
      city: event.city,
      etype: event.etype,
      geopoint: event.geopoint
    });
}}

здесь: я обновлю оба https://github.com/geofirestore/geofirestore-js/issues/154

1 Ответ

0 голосов
/ 10 февраля 2020

От разработчика Geofirestore также есть обсуждение и рабочий CORS для облачных функций

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

admin.initializeApp();

const firestoreRef = admin.firestore();
const geofirestore = new GeoFirestore(firestoreRef);
const geocollection = geofirestore.collection('planner');

exports.chooseCity = functions.https.onRequest(async (request, response) => {
  if (request.method === 'OPTIONS') {
    response.set('Access-Control-Allow-Methods', 'POST');
    return response.status(200).send({});
  } else {
    const radius = request.body.distance;
    const center = new admin.firestore.GeoPoint(request.body.location[0],
request.body.location[1]);

    // The data from a doc is returned as a function,
       // so you just need to map and call the function
           // sendit returns a single promise
    const sendit = (await geocollection.near({ center, radius })
     .get())
     .docs
     .map((doc) => ({ ...doc, data: doc.data() }));

     return response.status(200).send({ sendit });
  }
 });
...