-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Server-Side Rendering and Preloading with Sapper #4
Comments
I'm also interested in this, i am currently leaking apki keys to the client, which is not ideal |
I do something similar and I don't know what is best: any.svelte <script>
let client;
onMount(async () => {
if(process.browser){
client = await import("../firebase/firebase.js");
// loading firebase stuff here with client.db or client.auth
// which are exported in the firebase.js
}
});
</script> the initialization I do in the client.js import * as sapper from '@sapper/app';
import firebase from 'firebase/app';
const firebaseConfig = { ... };
firebase.initializeApp(firebaseConfig);
sapper.start({
target: document.querySelector('#sapper')
}); |
I'm in the same boat here folks... having done a sapper project with tailwind which I find terrific and now I want to add the backend portion which will be firebase... I see the exact same issues with SSR that are linked above, I resorted to specifying What I ended up doing for now is but this in in my sapper <script defer src="https://www.gstatic.com/firebasejs/7.6.2/firebase-app.js"></script>
<script defer src="https://www.gstatic.com/firebasejs/7.6.2/firebase-auth.js"></script>
<script defer src="https://www.gstatic.com/firebasejs/7.6.2/firebase-firestore.js"></script>
<script defer src="https://www.gstatic.com/firebasejs/7.6.2/firebase-storage.js"></script>
<script defer src="https://www.gstatic.com/firebasejs/7.6.2/firebase-messaging.js"></script>
<script defer src="https://www.gstatic.com/firebasejs/7.6.2/firebase-performance.js"></script>
<script defer src="https://www.gstatic.com/firebasejs/7.6.2/firebase-analytics.js"></script>
<script defer src="./firebase-init.js"></script> and then have in my let config = {
apiKey: "zzzzz",
appId: "1:1xxxxxxxxx",
authDomain: "xxxxxxxxx",
databaseURL: "xxxxxx",
measurementId: "G-"xxxxx,
messagingSenderId: "xxxxxxxxxxx",
projectId: "xxxxxxxxxxx",
storageBucket: ""
}
firebase.initializeApp( config )
firebase.performance()
firebase.analytics() while this works, it gives me issues related to SSR such as I really hope there's going to be a proper solution for all folks that want to use firebase with some SSR app like Sapper (Svelte toolkit for SSR), React SSR, or Angular SSR... at the moment, all I've seen are just
|
The issues around SSR builds and esm vs cjs seem to bite quite a few people now as this new issue elaborates too firebase/firebase-js-sdk#1612 |
by API keys do you mean the public config information that you put in
|
I've gotten a version of ssr and preloading up and running following this video: Essentially there needs to be 2 versions of Firestore loaded. He loads clientside firebase stuff like Jeff in the scripts and then has a conditional definition of Firestore export async function firestore() {
if (process.browser) {
return window.db
} else {
const firebase = await import('firebase')
const config = await import('./config');
if (firebase.apps.length == 0) {
let app = firebase.initializeApp(config.default)
return app.firestore()
}
else {
return firebase.apps[0].firestore()
}
}
} on the page I need preloaded data: <script context="module">
// load the above file
import { firestore } from "../../firebase/firestore";
export async function preload({ params, query }) {
let db = await firestore();
const data = await db
.collection("collection")
.doc(params.slug)
.get();
if (data.exists) {
return { document: data.data() };
} else {
this.error("no data");
}
}
</script>
<script>
// this document is returned from the preload and ready for usage in html
export let document;
</script> if the client.js import * as sapper from '@sapper/app';
import firebase from 'firebase/app';
import 'firebase/firestore';
import {default as config} from './firebase/config'
let app = firebase.initializeApp(config)
window.db = app.firestore()
sapper.start({
target: document.querySelector('#sapper')
}); edit: //--- rollup.config.js ---
commonjs({
namedExports: {
// left-hand side can be an absolute path, a path
// relative to the current directory, or the name
// of a module in node_modules
'node_modules/idb/build/idb.js': ['openDb'],
'node_modules/firebase/dist/index.cjs.js': ['initializeApp', 'firestore'],
},
}), |
@pjarnfelt that seems to be a good approach for now, I think it makes the initial app instance and firestore work nicely. Two more things I'd like to ask you
✗ client
'deleteDb' is not exported by node_modules/idb/build/idb.js
4: import { __values, __spread, __awaiter, __generator, __assign } from 'tslib';
5: import { ErrorFactory } from '@firebase/util';
6: import { deleteDb, openDb } from 'idb';
^
|
I fixed the |
so there's more info on this funthing and it seems others hit this roadblock before |
@evdama Yes, I did the named exports from your link. Forgot to mention that. Will edit my comment. yes I'm using performance and analytics, not storage though, but I suspect that would work too. I added them to the client.js where I instantiate the app. Now I'm just having trouble hosting it on firebase functions/hosting |
@pjarnfelt there you go https://dev.to/eckhardtd/how-to-host-a-sapper-js-ssr-app-on-firebase-hmb :) |
@evdama thanks for the link. I'm already doing that (hosting ssr through functions), but the troubles I'm having is that my performance is terrible. Now I got preloading and ssr on my firestore content and ssr-auth handling to avoid the front-end loading delay of the authentication (also based on a sveltecasts video). Now my first load on normal internet speed is around 10 sec and interaction around 18, which defies the whole purpose of Svelte/Sapper. |
@pjarnfelt Interessting, my site is much quicker to first inital paint, about 0.6 seconds or so... Either way, you must be doing something odd otherwise that can't be explained. Try with lighthouse and see what it tells you to improve. |
This seems to work wonders, but I can't seem to get this to work with SvelteFire; it complains that I don't have Anyone got any suggestions to get both this method of SSR and SvelteFire to work? |
I got some errors while using @pjarnfelt answer
firebase.js
Client side firestore works but SSR seems not working First issue I had was |
I finally use this way which work fine :
add this in client.js
and then you can access for the firestore aspect, because I use SSR and have SEO constraints, I only use hope this helps |
@sebmade Your solution looks nice! I'm having trouble getting it to work though. Do you mind sharing an example of how you use |
@alfrednerstu if you want to use |
@sebmade So you do everything twice? Both in |
@alfrednerstu no, because you can't compile ssr with firebase libs, so it depends of my needs, for authentication and when user is connected I use client side firebase call, when not I sue server side firebase call IDBIndex error is due to compilation of firebase lib, be sure to have firebase lib in devDependencies in your package.json and don't make firebase call in directly in preload function, just on the server side files. |
@sebmade would you be willing to provide some example code similar to @pjarnfelt post from Jan 16? Thanks |
Hey guys, I did not read the entire thread, but I just wanted to add my 2 cents. In my personal Sapper project I've written this file. https://github.com/Evertt/sapper-cms/blob/main/src/store/firebase.ts And it makes it possible to write So this would work perfectly if sveltefire would just try not to use any database APIs that are different between the web version of firebase and firebase-admin. |
Hey Evertt, |
Hello @vc-ca, |
Getting Sapper working with Firestore would be awesome. I've gotten Sapper SSR deployed to Firebase Cloud functions, which is really cool, but sapper not supporting firebase is very disappointing! I moved Firestore to devDependencies, but I'm still getting this error:
I tried adding I also don't get why I'd want firebase used from the server code at all? Isn't it correct that firebase should only run client side? Or am I misunderstanding something fundamental here? Either way, what's the reasonable solution to using firebase with a Sapper/SSR web app? Is it really one of these methods of side-loading the dependency or sourcing it in template.html !? If so, what's the right way to do it? |
@makeitTim Firebase works with Sapper, I've already deploy a complete application using firestore, storage, stripe ... |
@sebmade Very cool! Are you using Firebase Hosting and Functions to host SSR? I still don't completely understand those choices ... why would I want to use firebase Firestore db on the sapper/ssr server side at all? (And isn't the firebase library specifically preventing it?) I think my use case is the typical and obvious one --- With a Sapper app I want to use Firestore as the backend and Firebase Auth for users to login and access their data. The app is comprised of detail screens of Firestore data and forms for updating the data. How do I do that? Is this library, sveltefire useful? It looks cool, but this whole lack of setup is worrying and makes me feel like I'd be more comfortable working directly with firebase app.db. Thanks! |
@makeitTim I have a working project using firestore both client-side and server-side (as in during SSR). Not using sveltefire though, but using my own firestore wrapper. My project is still very buggy, but it proves the concept at least. I'm a bit too lazy to explain though, so I'll just show you the code and the result. This code: Produces this website: editbtw don't think about the fact that the repo is called |
@makeitTim yes I use firebase hosting, I don't try to use @google-cloud/firestore api independently |
Opening an issue to determine the best way to work with Firebase in Sapper. Currently, bundling with rollup leads to issues that seem related to firebase/firebase-js-sdk#1797
One possible solution is to make Firebase global with script tags.
template.html
_layout.svelte
This works, but does not address how to preload data from Firebase.
The text was updated successfully, but these errors were encountered: