sveltejs / sapper

The next small thing in web development, powered by Svelte
https://sapper.svelte.dev
MIT License
7k stars 434 forks source link

any idea to combine rxfire with Sapper? #761

Closed jeffkenz89 closed 5 years ago

jeffkenz89 commented 5 years ago

i think firebase not compatible with server.js in sapper anybody can help? The XMLHttpRequest compatibility library was not found


!we())throw new M("internal-error","The XMLHttpRequest compatibility library was not found.");this.c=void 0;we()?this.c=new oh(self):ye()?this.c=new ai(c):this.c=new Zg;}var gi,ag="idToken",ci=new Me(3E4,6E4),di={"Content-Type":"application/x-www-form-urlencoded"},ei=new Me(3E4,6E4),fi={"Content-Type":"application/json"};function hi(a,b){b?a.a["X-Firebase-Locale"]=b:delete a.a["X-Firebase-Locale"];}```
evdama commented 5 years ago

can you please format the code use triple `

hitochan777 commented 5 years ago

can you show me how your server.js looks like?

mortscode commented 5 years ago

server.js:

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

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

polka() // You can also use Express
    .use(
        compression({ threshold: 0 }),
        sirv('static', { dev }),
        sapper.middleware()
    )
    .listen(PORT, err => {
        if (err) console.log('error', err);
    });
mortscode commented 5 years ago

I'm having the same problem with rxfire

mortscode commented 5 years ago

Also getting this:

[2019-06-24T21:55:03.033Z]  @firebase/app: 
      Warning: This is a browser-targeted Firebase bundle but it appears it is being
      run in a Node environment.  If running in a Node environment, make sure you
      are using the bundle specified by the "main" field in package.json.

      If you are using Webpack, you can specify "main" as the first item in
      "resolve.mainFields":
      https://webpack.js.org/configuration/resolve/#resolvemainfields

      If using Rollup, use the rollup-plugin-node-resolve plugin and set "module"
      to false and "main" to true:
      https://github.com/rollup/rollup-plugin-node-resolve

Attempted to use firebase on both Webpack and Rollup. I added the above suggestions to both which changed the error, but lead to other problems with different node dependencies.

hitochan777 commented 5 years ago

Looking at the firebase code, it does not seem to support Node environment. https://github.com/firebase/firebase-js-sdk/blob/master/packages/app/index.ts#L50

When I try to import firebase library in server.js, I also got the same warning, but importing it in the client.js did not give me any warnings.

Also, when I import it inside components, it also gave me the warning this is probably because the components are rendered with Node environment during SSR.

Below is my working pieces of code. Hope it helps.

client.js looks like this:

import * as sapper from "@sapper/app";

import "./firebase";
import "../assets/style.css";

sapper.start({
  target: document.querySelector("#sapper")
});

firebase.js looks like this:

import firebase from "firebase/app";
import "firebase/auth";

const firebaseConfig = {
 /*...*/
};

firebase.initializeApp(firebaseConfig);
kylecordes commented 5 years ago

In the comment there though, it points out how to get the server-side code. It's not that they don't support Node, it's that this particular bundle is their client-side bundle.

evdama commented 5 years ago

that's correct, with firebase you've got client-side as well as server-side SDKs. firebase-admin for example is server-side only. firebase-js-sdk on the other hand is client-side.

Just have a read at https://github.com/firebase/firebase-admin-node and you'll understand quickly.

evdama commented 5 years ago

I'm having the same problem with rxfire

you use rxfire from the client in order to talk to backendservices such as firestore (which are by default providing you with streams that you can consume on the client using rxfire).

Sapper & Firebase are an outstanding combo, you just have to grasp the concepts and when you do... it's brilliant and incredibly powerful.

https://firebase.googleblog.com/2018/09/introducing-rxfire-easy-async-firebase.html https://github.com/davideast/rxfire-samples https://github.com/firebase/firebase-js-sdk/tree/master/packages/rxfire

mortscode commented 5 years ago

@evdama thank you. I'm really trying to grasp it. I went through the Udemy course with Maxamillian, but his firebase approach using fetch() seems much more verbose and complicated than the rxfire approach I've used in the past.

Do you know of any code examples of how to set it up with Sapper so that both the client and the server are happy?

kylecordes commented 5 years ago

I wonder how much of the Firebase feature set (for example: authorization!) will work with server-side rendering in the generic sense. And of course relevant here, with Sapper specifically.

Certainly if anyone has a fully working example, ideally using both authorization and firestore, that would be an excellent thing to publish.

evdama commented 5 years ago

Do you know of any code examples of how to set it up with Sapper so that both the client and the server are happy?

with sapper you really just have to understand where (client vs server) a particular snippets needs to run. So any example code is fine as long as you put it in the right place really :)

evdama commented 5 years ago

I wonder how much of the Firebase feature set (for example: authorization!) will work with server-side rendering in the generic sense. And of course relevant here, with Sapper specifically.

Same as above, the SSR part of Sapper is a generic portion of your app i.e. no auth. A crawler and a non-authenticated user, they all get the same portion with sapper & firebase (substitute with AWS etc., all the same really).

Don't try to do something that sapper isn't intended to do (firebase/aws/etc. auth on the server). Sapper delivers your app shell and gets you fast inital paint. After rehydrating the static site on the client, it's ordinary auth & auth.

Understanding that and using the right tool for the right portion of you app I think gives you the overall best stack that you can build today. If not for sapper I would have had to build the entire SSR thingy for SEO by hand which would be months and months of time and effort. Love Sapper. So good.

mortscode commented 5 years ago

My hope is to have a firebase.js file in my project somewhere that initializes firebase. Something like this:

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

const firebaseConfig = {
    apiKey: '...',
    authDomain: '...',
    databaseURL: '...',
    projectId: '...',
    storageBucket: '...',
    messagingSenderId: '...',
    appId: '...',
};

firebase.initializeApp(firebaseConfig);

export const auth = firebase.auth();
export const googleProvider = new firebase.auth.GoogleAuthProvider();

export const db = firebase.firestore();

...and then I'd like to use it in my .svelte templates like this:

<script>
    import { auth, googleProvider } from '../utils/firebase.js';
    import { authState } from 'rxfire/auth';
    let user = authState(auth);
    function login() {
        auth.signInWithPopup(googleProvider);
    }
</script>

So far, this approach is breaking my server with the errors at the top of this thread.

Any thoughts on how to use firebase in the above modular fashion on Sapper?

Just looking to utilize auth and firestore.

hitochan777 commented 5 years ago

I created a repository for sapper with firebase authentication. https://github.com/hitochan777/sapper-firebase-auth-example.

evdama commented 5 years ago

I started with this and modified minor bits, added .ts support and tailwind... https://dev.to/muhajirdev/using-tailwindcss-with-sveltejs-2098https://github.com/mightyjol/sapper-firebase-template works like charm, app is SSRing like a boss really :)

also check https://dev.to/eckhardtd/how-to-host-a-sapper-js-ssr-app-on-firebase-hmb

rxfire is the last bit you add but then it's shipped with the fb client sdk already so you just have to use it

kylecordes commented 5 years ago

@hitochan777 That is very cool, but monkey patching Sapper with a sed is pretty deep in the toolbox. By any chance is there an open issue or PR to get the needed change “in the box”?

@evdama Conveniently your start exactly matches one of my use cases, thank you!

hitochan777 commented 5 years ago

@kylecordes I've created a PR (https://github.com/sveltejs/sapper/pull/743) but it is yet to be merged.

mortscode commented 5 years ago

@evdama as you can see in my comment above, the config blob from firebase looks like this:

const firebaseConfig = {
    apiKey: '...',
    authDomain: '...',
    databaseURL: '...',
    projectId: '...',
    storageBucket: '...',
    messagingSenderId: '...',
    appId: '...',
};

Your config in config/serviceAccount.js looks like this:

export default {
    "type": "service_account",
    "project_id": "your project id",
    "private_key_id": "",
    "private_key": "",
    "client_id": "",
    "auth_uri": "",
    "token_uri": "",
    "auth_provider_x509_cert_url": "",
    "client_x509_cert_url": ""
}

Am I looking in the wrong place within firebase for this config info? I'm using the firebase web application (</>) for my project.

evdama commented 5 years ago

yup, as mentioned on discord [8:27 PM] evdama: yeah, don't confuse the two [8:28 PM] evdama: the first gets shipped with your code to the client [8:28 PM] evdama: second one is on the backend [8:28 PM] evdama: first one is mandatory [8:29 PM] evdama: second one... in eight out of ten cases you want/need it too [8:29 PM] evdama: you'll get both from you firebase console [8:29 PM] evdama: copy/paste it and you're good`

`

atomobianco commented 5 years ago

Along the lines of this open issue, the repository by @drejohnson works with rxfire https://github.com/drejohnson/sappper-starter-graphql

Although the firebase auth is still happening client side, hence with page rendered as logged-out, and then changing once the firebase api call returns.

kylecordes commented 5 years ago

@atomobianco I looked at that code very very briefly, and probably could answer the following question myself with a longer look and research. But for the sake of others on the thread, it would be super helpful to answer:

Can you link to the specific spot in that example where there is some kind of branch between client-side rendering and server-side rendering? Such that the server-side doesn't even attempt to run (presumably nonexistent) code to check for being logged in, while the client-side execution does so?

atomobianco commented 5 years ago

I don't fully understand your question - nor the code of that template; you better ask the author of that template.

pngwn commented 5 years ago

Github issues should be reserved for feature requests or bug reports. Support questions should be directed to the Svelte / Sapper Discord Chat or asked at Stack Overflow with the svelte/sapper tags.

jdgamble555 commented 3 years ago

To use Firebase with Sapper / SvelteKit on the backend, see my stackoverflow.