5

I want to use Cloud Functions for Firebase to deploy the React application for shopify app.

I am new to both Next and Koa.

Based on this repo the below code is how to host a simple react application in Firebase.

const path = require('path')
const functions = require('firebase-functions')
const next = require('next')

var dev = process.env.NODE_ENV !== 'production'
var app = next({
  dev,
  conf: { distDir: `${path.relative(process.cwd(), __dirname)}/next` }
})
var handle = app.getRequestHandler()

exports.next = functions.https.onRequest((req, res) => {
  console.log('File: ' + req.originalUrl) // log the page.js file that is being requested
  return app.prepare().then(() => handle(req, res))
})

Which works correctly, no issue.

Then based on this tutorial from shopify I need to integrate koa and other dependencies in server.js, which in my case I believe it should be placed inside the firebase function. so I get to this code

const path = require('path')
const isomorphicFetch = require('isomorphic-fetch');
const Koa = require('koa');
const functions = require('firebase-functions')
const next = require('next');
const ShopifyConfig = require('./shopify.js');

const { default: createShopifyAuth } = require('@shopify/koa-shopify-auth');
const dotenv = require('dotenv');
const { verifyRequest } = require('@shopify/koa-shopify-auth');
const session = require('koa-session');

dotenv.config();

const port = parseInt(process.env.PORT, 10) || 3000;

var dev = process.env.NODE_ENV !== 'production'
var app = next({
  dev,
  conf: { distDir: `${path.relative(process.cwd(), __dirname)}/next` }
})
var handle = app.getRequestHandler()

const server = new Koa();

server.use(session(server));
server.keys = [ShopifyConfig.secretKey];

server.use(
  createShopifyAuth({
    apiKey: ShopifyConfig.key,
    secret: ShopifyConfig.secretKey,
    scopes: [],
    afterAuth(ctx) {
      const { shop, accessToken } = ctx.session;
      ctx.redirect('/');
    },
  }),
);

server.use(verifyRequest());

server.use(async (ctx) => {
  await handle(ctx.req, ctx.res);
  ctx.respond = false;
  ctx.res.statusCode = 200;

});

exports.next = functions.https.onRequest((req, res) => {
  console.log('File: ' + req.originalUrl) // 

  // This is old code
  // return app.prepare().then(() => {
  //   handle(req, res);
  // })

  // I tried this #1
  // server.callback(req, res);
})

// I tried this #2
// exports.next = functions.https.onRequest(server.callback);

// I tried this #3
// exports.next = functions.https.onRequest(server.callback());

// I tried this #4
exports.next = functions.https.onRequest((req, res) => {
  console.log('File: ' + req.originalUrl) 

  return app.prepare().then(() => {
    server.callback(req, res);
    //handle(req, res);
  })
})

My question is now based on Koa what code should be in functions.https.onRequest ? please note there is no code to listen to port since it doesn't make sense for firebase functions.

I tried #1, #2, #3, as well as this post

1 -> I get request timeout

2 -> I get request timeout

3 -> I get "Cannot access middleware of undefined"

4 -> I get request timeout

juliomalves
  • 42,130
  • 20
  • 150
  • 146
Reza
  • 18,865
  • 13
  • 88
  • 163
  • make sure you return a promised (this is key), your are getting timeouts because of that, everything else seems to be correct, I assume you want to manage your routes into koa and delegate a single point of entry on the next function, right? – andresmijares Jun 03 '19 at 13:41
  • @andresmijares I am new to both koa and next, these are instructions from shopify documentation, so I think the answer to your question is yes. In the documentation at the end server listens to port 3000, what should be in firebase function, instead I tried to use server.call back which is void, then I trie to return a new Promise and resolve after callback and still same – Reza Jun 03 '19 at 13:55
  • it's cors problem... if you can elaborate a little bit adding cors to your function it will be easier to help u :) – andresmijares Jun 05 '19 at 03:16
  • @andresmijares when it's like that `exports.next = functions.https.onRequest((req, res) => { console.log('File: ' + req.originalUrl) // log the page.js file that is being requested return app.prepare().then(() => handle(req, res)) })` working fine, I don't think it will be related to cors – Reza Jun 05 '19 at 13:12

2 Answers2

0

Thanks to kvindasAB

server.callback is not the callback by itself, rather a function that generates the callback from your configuration I assumed.

so code needs to be changed to

server.callback()(req, res);
Reza
  • 18,865
  • 13
  • 88
  • 163
0
const functions = require('firebase-functions');
const app = new Koa();

...

exports['http'] = functions.https.onRequest(app.callback());
Tom
  • 471
  • 3
  • 11
  • 4
    The provided answer was flagged for review as a Low Quality Post. Here are some guidelines for [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer). This provided answer may be correct, but it could benefit from an explanation. Code only answers are not considered "good" answers. From [review](https://stackoverflow.com/review). – MyNameIsCaleb Sep 22 '19 at 00:48