6

I'm trying to implement firebase in Sapper. I installed the modules (@firebase/app, @firebase/auth, @firebase/firestore) and then I wrote a configuration file:

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

const config = {
...
};

// Initialize Firebase
firebase.initializeApp(config);
export { firebase };
// Initialize db
export const db = firebase.firestore();
export const auth = firebase.auth();

When I "npm run dev", I got an error saying that those firebase modules are intended only for client side and not for Node.js.

So, I tried to fix this problem in many ways and the only one that seems to work so far is using onMount.

  onMount(async () => {
    const {auth} = await import('../firebase/config');
    auth.signInWithEmailAndPassword("test@gmail.com", "test").then((res) => {
      // do some stuff
    })
  })

Now it works, but I've 3 questions:

1) is this the right way? 2) should I remove those modules from server side or is better to keep them anyway? 3) should I use both client side and server side versions of firebase and use client side one to retrieve all the data that are different for each visitor and server side to all the data in common?

Vincenzo Lombino
  • 241
  • 4
  • 10

3 Answers3

4

I would check process.browser

  onMount(async () => {
    if (process.browser) {
      const {auth} = await import('../firebase/config');
      auth.signInWithEmailAndPassword("test@gmail.com", "test").then((res) => {
        // do some stuff
      })
    }
  })

or

if (process.browser) {
  onMount(async () => {
    const {auth} = await import('../firebase/config');
    auth.signInWithEmailAndPassword("test@gmail.com", "test").then((res) => {
      // do some stuff
    })
  })
}
Michola Ultra
  • 145
  • 1
  • 13
3

I'd say you are pretty close, but you can keep the import out of the onMount callback:

<script>
import { auth } from '../firebase/config';
import { onMount } from 'svelte'

onMount(() => {
    auth.signInWithEmailAndPassword("test@gmail.com", "test").then((res) => {
      // do some stuff
    })
})
</script>

If you do it this way, your firebase code won't be called during the SSR and you won't have to deal with async module loading.

With that said, I'd argue that placing your firebase code in a server route, and calling that route from the client is probably a cleaner and more efficient way to do it.

Morphyish
  • 3,932
  • 8
  • 26
0

You can use:

typeof window === 'undefined' // server
typeof window !== 'undefined' // client

Source

David Wolf
  • 1,400
  • 1
  • 9
  • 18