Firebase deployng Sapper app as cloud function failed

246 views Asked by At

The problem

I'm building Sapper SSR app that loads content from Firebase storage based on data required from Firebase realtime database. My app is deployed on Firebase cloud functions. But last time I deployed I got this error, since last deploy I implemented loading some data from realtime database and other minor features, so I don't know what is causing this error.

Deploy command:

/usr/bin/node /usr/local/lib/node_modules/npm/bin/npm-cli.js run deploy:functions --scripts-prepend-node-path=auto

> [email protected] deploy:functions /home/hejtmus/Documents/Websites/Violette/sapper/Violette/functions
> firebase deploy --only functions:ssr


=== Deploying to 'violette-77756'...

i  deploying functions
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i  functions: ensuring required API cloudbuild.googleapis.com is enabled...
✔  functions: required API cloudbuild.googleapis.com is enabled
✔  functions: required API cloudfunctions.googleapis.com is enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (4.41 MB) for uploading
✔  functions: functions folder uploaded successfully
i  functions: current functions in project: ssr(us-central1)
i  functions: uploading functions in project: ssr(us-central1)
i  functions: updating Node.js 12 function ssr(us-central1)...
⚠  functions[ssr(us-central1)]: Deployment error.
Function failed on loading user code. Error message: Error: please examine your function logs to see the error cause: https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs


Functions deploy had errors with the following functions:
        ssr


To try redeploying those functions, run:
    firebase deploy --only "functions:ssr"


To continue deploying other features (such as database), run:
    firebase deploy --except functions

Error: Functions did not deploy properly.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] deploy:functions: `firebase deploy --only functions:ssr`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] deploy:functions script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/hejtmus/.npm/_logs/2020-09-27T18_34_13_296Z-debug.log

Process finished with exit code 1

Firebase logs:

Error: function terminated. Recommended action: inspect logs for termination reason. Function cannot be initialized.

{"@type":"type.googleapis.com/google.cloud.audit.AuditLog","status":{"code":3,"message":"Function failed on loading user code. Error message: Error: please examine your function logs to see the error cause: https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs"},"authenticationInfo":{"principalEmail":"[email protected]"},"serviceName":"cloudfunctions.googleapis.com","methodName":"google.cloud.functions.v1.CloudFunctionsService.UpdateFunction","resourceName":"projects/violette-77756/locations/us-central1/functions/ssr"}

What I tried

I tried:

  • running app in dev mode, works perfect

  • building app as js function, works perfect

  • serving app via firebase serve, works perfect

  • deploying app using firebase deploy or firebase deploy --only functions, none of them works, throws above specified error

  • checking code for errors and misconfiguration, found nothing

I tried solving this problem with knowledge from this article, I followed this tutorial form step to step, but I still got the same error:

https://blog.logrocket.com/build-an-ssr-web-app-with-firebase-functions-hosting-and-svelte-sapper/

I tried also removing code I added and deployng app without loading data from firebase realtime database, but it didn't help.

Code:

index.js (cloud functions):

const functions = require('firebase-functions');
const { sapperServer } = require('./__sapper__/build/server/server');

exports.ssr = functions.https.onRequest(sapperServer);

server.js:

import sirv from 'sirv';
import express from 'express';
import compression from 'compression';
import * as sapper from '@sapper/server';

const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';

const sapperServer = express()
    .use(
        compression({ threshold: 0 }),
        sirv(`static`, { dev }),
        sapper.middleware()
    )
if(dev){
    sapperServer.listen(PORT, err => {
        if (err) console.log('error', err);
    });
}

export { sapperServer }

I will provide more info if needed.

1

There are 1 answers

0
Hejtmus On BEST ANSWER

What was the problem

The problem was, that I used firebase for browser, Svelte is compiler an it runs in Node.js environment, it has to be bundled by code bundler (I use rollup). To be able to run firebase in node, just specify mainFields in rollup configuration.

resolve({
    browser: true,
    dedupe: ['svelte'],
    mainFields: ['main']
}),

I use firebase only in client, so there is no need to specify mainFields parameter in server in my case.

Full rollup configuration

import resolve from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import commonjs from '@rollup/plugin-commonjs';
import svelte from 'rollup-plugin-svelte';
import postcss from 'rollup-plugin-postcss';
import autoPreprocess from "svelte-preprocess";
import pluginJson from "@rollup/plugin-json";
import babel from 'rollup-plugin-babel';
import { terser } from 'rollup-plugin-terser';
import config from 'sapper/config/rollup.js';
import pkg from './package.json';

const mode = process.env.NODE_ENV;
const dev = mode === 'development';
const legacy = !!process.env.SAPPER_LEGACY_BUILD;

const onwarn = (warning, onwarn) => (warning.code === 'CIRCULAR_DEPENDENCY' && /[/\\]@sapper[/\\]/.test(warning.message)) || onwarn(warning);

const preprocessOptions = {
    postcss: {
        plugins: [
            require('postcss-import'),
            require('postcss-preset-env')({
                stage: 0,
                browsers: 'last 2 versions',
                autoprefixer: { grid: true }
            })
        ]
    }
};

export default {
    client: {
        input: config.client.input(),
        output: config.client.output(),
        plugins: [
            replace({
                'process.browser': true,
                'process.env.NODE_ENV': JSON.stringify(mode)
            }),
            svelte({
                preprocess: autoPreprocess(preprocessOptions),
                dev,
                hydratable: true,
                emitCss: true,
                css: css => {
                    css.write('static/css/bundle.css');
                }
            }),
            postcss({
                extract: "static/css/imported.min.css",
                sourceMap: true,
                minimize: true,
            }),
            resolve({
                browser: true,
                dedupe: ['svelte'],
                mainFields: ['main']
            }),
            commonjs(),
            legacy && babel({
                extensions: ['.js', '.mjs', '.html', '.svelte'],
                runtimeHelpers: true,
                exclude: ['node_modules/@babel/**'],
                presets: [
                    ['@babel/preset-env', {
                        targets: '> 0.25%, not dead'
                    }]
                ],
                plugins: [
                    '@babel/plugin-syntax-dynamic-import',
                    ['@babel/plugin-transform-runtime', {
                        useESModules: true
                    }]
                ]
            }),

            !dev && terser({
                module: true
            })
        ],

        onwarn,
    },

    server: {
        input: config.server.input(),
        output: config.server.output(),
        plugins: [
            replace({
                'process.browser': false,
                'process.env.NODE_ENV': JSON.stringify(mode)
            }),
            svelte({
                preprocess: autoPreprocess(preprocessOptions),
                generate: 'ssr',
                dev,
                css: css => {
                    css.write('static/css/bundle.css');
                }
            }),
            postcss({
                extract: "static/css/imported.min.css",
                sourceMap: true,
                minimize: true,
            }),
            resolve({
                dedupe: ['svelte']
            }),
            commonjs(),
            pluginJson(),
        ],
        external: Object.keys(pkg.dependencies).concat(
            require('module').builtinModules || Object.keys(process.binding('natives'))
        ),

        onwarn,
    },

    serviceworker: {
        input: config.serviceworker.input(),
        output: config.serviceworker.output(),
        plugins: [
            resolve(),
            replace({
                'process.browser': true,
                'process.env.NODE_ENV': JSON.stringify(mode)
            }),
            commonjs(),
            !dev && terser()
        ],

        onwarn,
    }
};