Problem
I have a Flutter Web project hosted on Firebase Hosting rendered with CanvasKit and I can't make it load external images hosted in a Xano CDN or load GooglePlaces API results (autocompiling).
I read many other solutions (like this or this or this) but none works. I also configured CORS on Google Cloud.
My files
This is my firebase.json file:
{
"hosting": {
"public": "build/web",
"ignore": [
"firebase.json",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
],
"headers": [
{
"source": "*",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
}
]
}
}
In index.html I have appended the following script, right before the </body> tag:
<!-- Firebase -->
<script type="module">
// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.6.10/firebase-app.js";
import { getAnalytics } from "https://www.gstatic.com/firebasejs/9.6.10/firebase-analytics.js";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: *mykey*,
authDomain: "hearth-148b0.firebaseapp.com",
projectId: "hearth-148b0",
storageBucket: "hearth-148b0.appspot.com",
messagingSenderId: *id*,
appId: *myappid*,
measurementId: *id*
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
</script>
I tried to include the header in the CachedNetworkImage:
return CachedNetworkImage(
httpHeaders: {"Access-Control-Allow-Origin": "*"},
imageUrl: imageUrl,
fit: fit,
width: width,
height: height,
progressIndicatorBuilder: (context, url, downloadProgress) =>
LoadingPlaceholder(width: width),
errorWidget: (context, url, error) => SizedBox(width: width),
);
And I tried to include the headers in GooglePlace initializer:
final GooglePlace googlePlace = GooglePlace(
kTokenGMaps,
headers: {"Access-Control-Allow-Origin": "*"},
);
The errors
These are the type of errors I get from the browser console:
Failed to load resource: net::ERR_BLOCKED_BY_CLIENT
or
Access to XMLHttpRequest at
'https://storage.googleapis.com/xatr-ly1x-gkt1.n7.xano.io/vault/xhL5_hu1/fMPW0YCx/C01_Ng../9de15d31/Monumento_ai_caduti_in_Corso_Europa.jpg'
(redirected from
'https://xatr-ly1x-gkt1.n7.xano.io/vault/xhL5_hu1/fMPW0YCx/C01_Ng../Monumento_ai_caduti_in_Corso_Europa.jpg?tpl=big:box')
from origin 'https://hearth-148b0.web.app' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the
requested resource.
Deploy
These are the commands I use to deploy on firebase, from android studio:
flutter build web
firebase deploy
Alternative
I also tried to use another host with FTP and setting the .htaccess file to:
Header set Access-Control-Allow-Origin *
but no success.
Related
I started a Quasar V2 app using the quasar CLI with vite config and ssr build. I can't seem to return the firebase functions handler from dist/ssr/index.js as suggested in the docs.
I've tried this with the webpack Quasar V2 config and it works fine.
I ran firebase init then installed firebase-functions and firebase-admin in the root dir.
I changed the source of functions to dist/ssr where I built my ssr app. I also edited hosting to send requests to the function "handler".
firebase.json
"functions": {
"source": "dist/ssr",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
]
},
"hosting": {
"public": "dist/ssr",
"rewrites": [
{
"source": "**",
"function": "handler"
}
],
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
},
I then returned the handler function, following the instructions from the quasar docs
server.js
import * as functions from "firebase-functions";
export const listen = ssrListen(async ({ app, port, ssrHandler }) => {
if (process.env.DEV) {
await isReady();
return app.listen(port, () => {
if (process.env.PROD) {
console.log("Server listening at port " + port);
}
});
} else {
return {
handler: functions.https.onRequest(ssrHandler),
};
}
});
I then ran "npm install" on both the root directory and the dist/ssr directory to make sure everything is fine.
then when I ran "firebase serve" I get back this result in localhost:5000 "Function us-central1-handler does not exist, valid functions are:" Whats going on :(
I want to deploy my NextJS SSG build into Firebase but after enabling webframeworks experiment Firebase CLI runs its own build commands and try to deploy to my free plan Firebase project, and fails at the end saying that I need to enable Functions. How can I deploy my SSG website to firebase in Firebase CLI?
BTW, I dont have any functions folder, nor is it specified in firebase config. I user Mantine for UI and it supports SSG. Looks like the CLI does some assuming to check for funcitons too (after reading the docs I disabled NextJS Image optimization and I dont have any redirects, rewrites, or headers in next.config.js). If possible can I disable this automatic creation of a functions?
Here is my firebase.json;
{
"hosting": {
"site": "xxxxxxxxxxx",
"source": ".",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
Here is my next.config.js;
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
images: {
unoptimized: true
}
}
module.exports = nextConfig
whenever I run a local server of my HTML page I get this error in the console (cloud functions are NOT being hosted locally):
GET https://www.gstatic.com/firebase/9.16.0/firebase-firestore.js net::ERR_ABORTED 404
GET https://www.gstatic.com/firebase/9.16.0/firebase-functions.js net::ERR_ABORTED 404
I am aware that this is a topic that has been asked about before, but none of the solutions others came to has helped me in any way. The other modules load fine. Here is my reference to all the modules in my HTML:
<script src="https://www.gstatic.com/firebasejs/8.8.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.8.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.8.0/firebase-analytics.js"></script>
<script src="https://www.gstatic.com/firebase/9.16.0/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebase/9.16.0/firebase-functions.js"></script>
Here is my firebase config at the beggining of my JS:
var firebaseConfig = {
apiKey: "AIzaSyB_gTZfsFfyrn_xsnNmtWuUMQkoyuHztts",
authDomain: "form-ce7e9.firebaseapp.com",
projectId: "form-ce7e9",
storageBucket: "form-ce7e9.appspot.com",
messagingSenderId: "479728355456",
appId: "1:479728355456:web:e7ce8a6a21e33cd176fe65",
measurementId: "G-GHTPHK5QXS"
Here is my index.js which I have deployed successfully:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
// add trigger (new user signup)
exports.newUserSignup = functions.auth.user().onCreate((user) => {
// for background triggers you must return a value/promise
return admin.firestore().collection("users").doc(user.id).set({
email: user.email,
cybos: [],
});
});
And finally here is my firebase.JSON:
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
]
},
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
Any help we be greatly appreciated, I'm about to be tearing my hair out
UPDATE:
This message appeared another time I ran the HTML on a local server:
Failed to load resource: the server responded with a status of 404 ()
It appears twice, once for firestore and once for functions
If anyone else is running into this issue it was actually a really simple solution, so I feel pretty dumb. I had the incorrect url's for the script reference, check this link for all of the appropriate links. My version number was incorrect is what it boiled down to.
This is what my guess would be for my firebase.json rewrites.
"rewrites": [
{
"source": "/api",
"function": "api"
},
{
"source": "**",
"destination": "/index.html"
}
]
Do the rewrites evaluate in order (in this case, checking the /api route first before **)?
If not, can I send all routes to my express function and just handle the routing to the static react files there?
"rewrites": [
{
"source": "**",
"function": "express"
}
]
const functions = require('firebase-functions')
const express = require('express')
const path = require('path');
const app = express()
// Init Middleware
app.use(express.json({ extended: false }));
// Define Routes
app.use('/api/users', require('./routes/users'));
app.use('/api/auth', require('./routes/auth'));
app.use('/api/contacts', require('./routes/contacts'));
// Serve static assets in production
if (process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static('client/build'));
app.get('*', (req, res) =>
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'))
);
}
exports.express = functions.https.onRequest(app)
Do the rewrites evaluate in order (in this case, checking the /api route first before **)?
Yes. This is explicitly stated in the documentation:
Important: Within the rewrites attribute, Hosting applies the rewrite defined by the first rule with a URL pattern that matches the requested path. So, you need to deliberately order the rules within the rewrites attribute.
This lets you serve both dynamic and static content.
I am building a static website with HTML, CSS & JS and hosted on firebase hosting and connected a custom domain. The only serverside function I need is to send mail from the contact form. For this, I am trying to use Firebase cloud function. I have initialized functions on the same project and trying to use firebase hosting rewrites to rewrite the request to mydomain.com/contact to the contact function. But when I try to access the mydomain.com/contact in the browser it shows the below 403 Forbidden error message.
Error: Forbidden
Your client does not have permission to get URL /contact/contact from this server.
firebase.json
{
"hosting": {
"public": "build",
"rewrites": [{
"source": "/contact",
"function": "contact"
}],
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}
}
The cloud function (not implemented the actual logic)
import * as functions from 'firebase-functions';
exports.contact = functions.https.onRequest((request, response) => {
response.send("<h1>Contact<h1>");
});
I am using Firebase spark plan.
This works for me:
"rewrites": [
{
"source": "**",
"function": "myApp"
}
]
And in the express function,
import * as functions from 'firebase-functions';
import express from 'express';
const app = express();
app.get('/contact', (req, res) => {
res.send("<h1>Contact<h1>");
};
export const myApp = functions.https.onRequest(app);
I had the same issue this week. I had a rewrite from /user to a function called user and I was getting the response Your client does not have permission to get URL /user/user from this server.
I just deleted the functions from the firebase console then deployed them again and now they work. There must be some occasional bug with deploying functions like this and/or using hosting rewrites where the rewrite path gets appended to the function url path on the server.