Firebase: как вызвать функцию HTTP onRequest в функции onCreate базы данных реального времени? - PullRequest
0 голосов
/ 31 января 2019

После нажатия кнопки «Оформить заказ» в моем приложении для электронной коммерции VueJS в дочернем узле «Заказы» моей базы данных будет создано новое поле «Заказ», содержащее параметры заказа.Я создал функцию Realtime Database onCreate 'newBuyerOrder', чтобы отправить пользователю электронное письмо, уведомляющее его об этом новом заказе, как только будет создано новое поле 'order'.Теперь я также хотел бы вызвать REST API «/ checkout», который я построил с помощью функции HTTPsReRequest, для обработки заказа через Paypal REST SDK.Как я могу это сделать?

Обходной путь, который я пробовал, заключается в создании функций HTTP onCall, которые клиентский браузер может вызывать для обработки заказа через Paypal с параметрами заказа и отправки электронной почты отдельно с помощью 'newBuyerOrder'Функция onCreate.Но, к сожалению, HTTP OnCall не позволяет перенаправить клиента.И, о чудо, при выполнении вызовов Paypal REST требуется перенаправление клиента, поэтому HTTPs onCall не работает для моей цели.

в functions / package.json

"dependencies": {
    "@sendgrid/mail": "^6.3.1",
    "firebase-admin": "~6.0.0",
    "firebase-functions": "^2.1.0",
    "paypal-rest-sdk": "^1.8.1"
}

в functions / src/index.ts

import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import * as sendgrid from  '@sendgrid/mail'
import * as paypal from  'paypal-rest-sdk'

// init firebase admin
admin.initializeApp()

// set sendgrid api in function config
const SENDGRID_API_KEY = ...

// set paypal api in function config
paypal.configure({
  ...
});

// setup paypal payment object and redirect user to paypal payment 
page
export const checkout = functions.https.onRequest((req, res) => {
// 1.Set up a payment information object, Build PayPal payment 
request
  const payReq = JSON.stringify({
    ...
  })
// 2.Initialize the payment and redirect the user.
  paypal.payment.create(payReq, (error, payment) => {
    if (error) {
      // handle error
    } else {
      // redirect to paypal approval link
      for (let i = 0; i < payment.links.length; i++) {
        if (payment.links[i].rel === 'approval_url') {
          res.redirect(302, payment.links[i].href)
        }
      }
    }
  })
})


// send email and trigger paypal checkout api given new buyer order
export const newBuyerOrder = functions.database
.ref('users/{userId}/orders/{orderId}')
.onCreate((snapshot, context) => 
    // expected solution to call 'checkout' REST API from above
    // send email via sendgrid
    const msg = {...}
    return sendgrid.send(msg)
})

Я ожидаю, что API '/ checkout' будет вызываться после создания нового поля заказа в базе данных реального времени и перенаправления клиента на страницу подтверждения Paypal.

1 Ответ

0 голосов
/ 31 января 2019

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

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

Или вы можете извлечь бизнес-функциональностьэтой функции облака, и поместите ее в обычную функцию JavaScript, чтобы вы вызывали ее из триггерной функции базы данных реального времени.


Триггер базы данных поступает из базы данных реального времени в функции облака.Код клиентского приложения не задействован, поэтому его также нельзя перенаправить.

Если вы хотите отправить ответ обратно клиенту после завершения операции, вы обычно записываете ответ для клиента обратно в базу данных в месте, которое клиент наблюдает.Например, вы можете написать ответ на: /users/{userId}/order_results/{orderId}, и тогда клиент может дождаться значения в этом месте .

...