[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"post:authentication-with-vuejs-and-firebase":3},{"type":4,"post":5,"relatedPosts":72,"seo":105,"alternates":107,"editable":110},"post",{"id":6,"title":7,"slug":8,"url":9,"excerpt":10,"reading_minutes":11,"blocks":12,"toc":35,"category":55,"tags":59,"cover":70,"published_at":71},3,"Authentication with Firebase and VueJS","authentication-with-vuejs-and-firebase","\u002Fblog\u002Fauthentication-with-vuejs-and-firebase","Build Firebase authentication in Vue with Pinia, GitHub login, session-aware route middleware, and protected authenticated and guest pages.",6,[13,17,20,23,26,29,32],{"type":14,"data":15},"general.rich-text",{"content":16},"\u003Cp>I've been developing VueJS and Firebase focused mini projects lately. After making a simple Chat Application with Firebase, I wanted to prepare a boilerplate for myself that includes Authentication and can also do middleware operations, and I made a mini gallery application by including the Firebase Storage feature. In this article, I will talk about how we can perform Firebase and Auth transactions with Pinia.\u003C\u002Fp>\n\u003Cp>Firebase is a platform developed by Google for building mobile and web applications. We can include the features that we want to use very quickly in many subjects in your project.\u003C\u002Fp>\n\u003Cp>The document is sufficient. I used GitHub Provider as Authentication, you can integrate different methods into your system if you wish. I used Pinia as state management in the auth part.\u003C\u002Fp>",{"type":14,"data":18},{"content":19},"\u003Ch2 id=\"firebase-configuration\">Firebase configuration\u003C\u002Fh2>\n\u003Cp>First of all, we do the Firebase integration,\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-javascript\">\u002F\u002F plugins\u002Ffirebase.js\nimport {initializeApp} from &quot;firebase\u002Fapp&quot;;\nimport { getAuth }from &quot;firebase\u002Fauth&quot;;\n\nconst firebaseConfig = initializeApp({\n    apiKey: &quot;&quot;,\n    authDomain: &quot;&quot;,\n    projectId: &quot;&quot;,\n    storageBucket: &quot;&quot;,\n    messagingSenderId: &quot;&quot;,\n    appId: &quot;&quot;,\n});\n\nconst auth = getAuth(firebaseConfig);\n\nexport {auth}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The \u003Ccode>firebaseConfig\u003C\u002Fcode> variable here contains the API Keys we received from Firebase. We then pass these variables as parameters to the \u003Ccode>getAuth\u003C\u002Fcode> function.\u003C\u002Fp>",{"type":14,"data":21},{"content":22},"\u003Ch2 id=\"router-and-middleware-setup\">Router and middleware setup\u003C\u002Fh2>\n\u003Cp>Now let's do the Auth operations. Since we will create middleware in the router section, we create a file called 'router.js' under the 'plugins' folder. Then we register it to the project in the \u003Ccode>main.js\u003C\u002Fcode> file.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-javascript\">\u002F\u002F plugins\u002Frouter.js\nimport {createRouter, createWebHistory} from 'vue-router';\n\nconst routes: [];\n\nconst router = createRouter({\n    history: createWebHistory(),\n    routes: routes,\n});\n\nexport default router;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>In the function we created below, if no middleware is defined for the relevant route, we continue the request with the \u003Ccode>next()\u003C\u002Fcode> function without any action. If middleware is defined, we run the relevant middleware function.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-javascript\">\u002F\u002F plugins\u002Frouter.js\nfunction nextFactory(context, middleware, index) {\n    const subsequentMiddleware = middleware[index];\n    if (!subsequentMiddleware) return context.next;\n    return (...parameters) =&gt; {\n        context.next(...parameters);\n        const nextMiddleware = nextFactory(context, middleware, index + 1);\n        subsequentMiddleware({...context, next: nextMiddleware});\n    };\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>In the function below, we register our middlewares with the \u003Ccode>beforeEach\u003C\u002Fcode> function.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-javascript\">\u002F\u002F plugins\u002Frouter.js\nrouter.beforeEach((to, from, next) =&gt; {\n    if (to.meta.middleware) {\n        const middleware = Array.isArray(to.meta.middleware) ? to.meta.middleware : [to.meta.middleware];\n        const context = {from, next, router, to};\n        const nextMiddleware = nextFactory(context, middleware, 1);\n        \n        return middleware[0]({...context, next: nextMiddleware});\n    }\n    return next();\n});\n\u003C\u002Fcode>\u003C\u002Fpre>",{"type":14,"data":24},{"content":25},"\u003Ch2 id=\"pinia-authentication-store\">Pinia authentication store\u003C\u002Fh2>\n\u003Cp>Now it's time for state management with Pinia. We create a file named \u003Ccode>authStore.js\u003C\u002Fcode> under the \u003Ccode>stores\u003C\u002Fcode> folder. In this file, we create a store using the \u003Ccode>defineStore\u003C\u002Fcode> function. In this store, we define variables with \u003Ccode>state\u003C\u002Fcode>, functions that we can read the values of variables with \u003Ccode>getters\u003C\u002Fcode>, and functions that we can change the values of variables and perform data operations with \u003Ccode>actions\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-javascript\">import { defineStore } from 'pinia'\nimport {\n    onAuthStateChanged,\n    GithubAuthProvider,\n    signInWithPopup,\n    signOut,\n} from &quot;firebase\u002Fauth&quot;;\nimport {auth} from &quot;@\u002Fplugins\u002Ffirebase&quot;;\nimport router from &quot;@\u002Fplugins\u002Frouter.js&quot;;\n\nexport const useAuthStore = defineStore('authStore', {\n    state: () =&gt; ({\n        userData: null,\n        loadingUser: false,\n        loadingSession: false,\n    }),\n    actions: {\n        async login() {\n            this.loadingUser = true;\n            try {\n                const provider = new GithubAuthProvider();\n                const { user } = await signInWithPopup(auth, provider);\n                this.userData = user;\n                await router.push(&quot;\u002F&quot;);\n            }catch (e) {\n                console.log(e)\n            }finally {\n                this.loadingUser = false;\n            }\n        },\n        async logout() {\n            try {\n                await signOut(auth);\n                this.userData = null;\n                await router.push(&quot;\u002Flogin&quot;);\n            }catch (e) {\n                console.log(e)\n            }\n        },\n        async checkSession() {\n            return new Promise((resolve, reject) =&gt; {\n                const unsubscribe = onAuthStateChanged(\n                    auth,\n                    (user) =&gt; {\n                        if (user) {\n                            this.userData = user;\n                        } else {\n                            this.userData = null;\n                        }\n                        resolve(user);\n                    },\n                    (e) =&gt; reject(e)\n                );\n                unsubscribe();\n            });\n        }\n    }\n})\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Here we are doing the login with Github in the \u003Ccode>login\u003C\u002Fcode> function. In the \u003Ccode>logout\u003C\u002Fcode> function, we log out with Firebase Auth. In the \u003Ccode>checkSession\u003C\u002Fcode> function, we check the session status of the user with Firebase Auth with the \u003Ccode>onAuthStateChanced\u003C\u002Fcode> function.\u003C\u002Fp>",{"type":14,"data":27},{"content":28},"\u003Ch2 id=\"using-the-store-in-pages\">Using the store in pages\u003C\u002Fh2>\n\u003Cp>Then we import and use this store wherever we want to use it. For example, when we want to use it on a page,\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-javascript\">import { useAuthStore } from '@\u002Fstores\u002FauthStore'\n\nconst authStore = useAuthStore()\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>We import as . In this way, we can access the variables and functions in the store with the \u003Ccode>authStore\u003C\u002Fcode> variable.\u003C\u002Fp>\n\u003Cp>Now for the pages. Under the \u003Ccode>pages\u003C\u002Fcode> folder, we create two files named \u003Ccode>Login.vue\u003C\u002Fcode> and \u003Ccode>Home.vue\u003C\u002Fcode>. In these files, we perform our operations by using the variables and functions in the store within the \u003Ccode>setup\u003C\u002Fcode> function.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-html\">&lt;script setup&gt;\n\u002F\u002F pages\u002FLogin.vue\nimport { useAuthStore } from '@\u002Fstores\u002FauthStore'\n\nconst authStore = useAuthStore()\n\nconst login = () =&gt; {\n  authStore.login()\n}\n&lt;\u002Fscript&gt;\n\n&lt;template&gt;\n    &lt;div&gt;\n        &lt;h1&gt;Login&lt;\u002Fh1&gt;\n        &lt;button @click=&quot;login&quot;&gt;Login&lt;\u002Fbutton&gt;\n    &lt;\u002Fdiv&gt;\n&lt;\u002Ftemplate&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>",{"type":14,"data":30},{"content":31},"\u003Ch2 id=\"protecting-authenticated-routes\">Protecting authenticated routes\u003C\u002Fh2>\n\u003Cp>It's time for middleware. We create a file named \u003Ccode>auth.js\u003C\u002Fcode> under the \u003Ccode>middleware\u003C\u002Fcode> folder. In this file, we check the session status of the user with the \u003Ccode>checkSession\u003C\u002Fcode> function that we created with \u003Ccode>useAuthStore\u003C\u002Fcode>. If the user is not logged in, we redirect to the \u003Ccode>login\u003C\u002Fcode> page.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-javascript\">\u002F\u002F middleware\u002Fauth.js\nimport {useAuthStore} from &quot;@\u002Fstores\u002FauthStore.js&quot;;\n\nexport default async function auth({next, router}) {\n    const userStore = useAuthStore();\n    userStore.loadingSession = true;\n    const user = await userStore.checkSession();\n    if (user) {\n        next();\n    } else {\n        next(&quot;\u002Flogin&quot;);\n    }\n    userStore.loadingSession = false;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Now for the \u003Ccode>router.js\u003C\u002Fcode> file. In this file, we add the \u003Ccode>auth\u003C\u002Fcode> middleware that we created as \u003Ccode>middleware\u003C\u002Fcode> to the \u003Ccode>meta\u003C\u002Fcode> part.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-javascript\">\u002F\u002F plugins\u002Frouter.js\nimport auth from &quot;@\u002Fmiddleware\u002Fauth.js&quot;;\n\nconst routes = [\n    {\n        path: &quot;\u002F&quot;,\n        name: &quot;Home&quot;,\n        component: () =&gt; import(&quot;@\u002Fpages\u002FHome.vue&quot;),\n        meta: {\n            middleware: auth,\n        },\n    },\n    {\n        path: &quot;\u002Flogin&quot;,\n        name: &quot;Login&quot;,\n        component: () =&gt; import(&quot;@\u002Fpages\u002FLogin.vue&quot;),\n    },\n];\n\u003C\u002Fcode>\u003C\u002Fpre>",{"type":14,"data":33},{"content":34},"\u003Ch2 id=\"protecting-guest-routes\">Protecting guest routes\u003C\u002Fh2>\n\u003Cp>Now let's do the reverse of this process. In other words, if the \u003Ccode>Login.vue\u003C\u002Fcode> page is logged in, it cannot be accessed. For this, we create a middleware again. We create a file named \u003Ccode>guest.js\u003C\u002Fcode> under the \u003Ccode>middleware\u003C\u002Fcode> folder. In this file, we check the session status of the user with the \u003Ccode>checkSession\u003C\u002Fcode> function that we created with \u003Ccode>useAuthStore\u003C\u002Fcode>. If the user is logged in, we are redirected to the 'Home' page.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-javascript\">\u002F\u002F middleware\u002Fguest.js\nimport {useAuthStore} from &quot;@\u002Fstores\u002FauthStore.js&quot;;\n\nexport default async function authCheck({next, router}) {\n    const userStore = useAuthStore();\n    userStore.loadingSession = true;\n    const user = await userStore.checkSession();\n    if (user) {\n        next(&quot;\u002F&quot;);\n    } else {\n        next();\n    }\n    userStore.loadingSession = false;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>As you can see, we do the opposite. Now for the \u003Ccode>router.js\u003C\u002Fcode> file. In this file, we add the \u003Ccode>guest\u003C\u002Fcode> middleware that we created as \u003Ccode>middleware\u003C\u002Fcode> to the \u003Ccode>meta\u003C\u002Fcode> part.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-javascript\">\u002F\u002F plugins\u002Frouter.js\nimport auth from &quot;@\u002Fmiddleware\u002Fauth.js&quot;;\nimport guest from &quot;@\u002Fmiddleware\u002Fguest.js&quot;;\n\nconst routes = [\n    {\n        path: &quot;\u002F&quot;,\n        name: &quot;Home&quot;,\n        component: () =&gt; import(&quot;@\u002Fpages\u002FHome.vue&quot;),\n        meta: {\n            middleware: auth,\n        },\n    },\n    {\n        path: &quot;\u002Flogin&quot;,\n        name: &quot;Login&quot;,\n        component: () =&gt; import(&quot;@\u002Fpages\u002FLogin.vue&quot;),\n        meta: {\n            middleware: guest,\n        },\n    },\n];\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Thus, we have done the session management operations using the Firebase Auth library in its simplest form, you can view the project by clicking the link below.\u003C\u002Fp>\n\u003Cp>That's it for now, see you in the next post. 👋🏼\u003C\u002Fp>\n\u003Cp>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fafsakar\u002Fvue-firebase-boilerplate\">Project Link\u003C\u002Fa>\u003C\u002Fp>",[36,40,43,46,49,52],{"id":37,"label":38,"level":39},"firebase-configuration","Firebase configuration",2,{"id":41,"label":42,"level":39},"router-and-middleware-setup","Router and middleware setup",{"id":44,"label":45,"level":39},"pinia-authentication-store","Pinia authentication store",{"id":47,"label":48,"level":39},"using-the-store-in-pages","Using the store in pages",{"id":50,"label":51,"level":39},"protecting-authenticated-routes","Protecting authenticated routes",{"id":53,"label":54,"level":39},"protecting-guest-routes","Protecting guest routes",{"id":56,"title":57,"slug":58},7,"Vue","vue",[60,62,66],{"id":61,"title":57,"slug":58},8,{"id":63,"title":64,"slug":65},11,"Firebase","firebase",{"id":67,"title":68,"slug":69},12,"Authentication","authentication",null,"2023-01-14",[73,90],{"id":39,"title":74,"slug":75,"url":76,"excerpt":77,"reading_minutes":39,"blocks":70,"toc":70,"category":78,"tags":79,"cover":70,"published_at":89},"Pinia vs Vuex","pinia-vs-vuex","\u002Fblog\u002Fpinia-vs-vuex","Compare Pinia and Vuex through simple state management examples, API differences, and practical guidance for choosing a store for your Vue application.",{"id":56,"title":57,"slug":58},[80,81,85],{"id":61,"title":57,"slug":58},{"id":82,"title":83,"slug":84},9,"Pinia","pinia",{"id":86,"title":87,"slug":88},10,"Vuex","vuex","2022-12-08",{"id":91,"title":92,"slug":93,"url":94,"excerpt":95,"reading_minutes":6,"blocks":70,"toc":70,"category":96,"tags":99,"cover":70,"published_at":104},1,"How do we sort arrays in PHP?","how-do-we-sort-arrays-in-php","\u002Fblog\u002Fhow-do-we-sort-arrays-in-php","Learn how PHP’s sort, rsort, asort, arsort, ksort, and krsort functions order indexed and associative arrays by values or keys.",{"id":11,"title":97,"slug":98},"PHP","php",[100,101],{"id":11,"title":97,"slug":98},{"id":56,"title":102,"slug":103},"Arrays","arrays","2022-10-09",{"html":106},"\u003Ctitle>Authentication with Firebase and VueJS - Azad Furkan Şakar\u003C\u002Ftitle>\n\u003Cmeta name=\"description\" content=\"Build Firebase authentication in Vue with Pinia, GitHub login, session-aware route middleware, and protected authenticated and guest pages.\">\n\u003Cmeta name=\"keywords\" content=\"laravel, backend, developer, php\">\n\u003Clink rel=\"canonical\" href=\"https:\u002F\u002Fafsakar.dev\u002Fblog\u002Fauthentication-with-vuejs-and-firebase\">\n\u003Clink rel=\"alternate\" hreflang=\"en\" href=\"https:\u002F\u002Fafsakar.dev\u002Fblog\u002Fauthentication-with-vuejs-and-firebase\">\n\u003Clink rel=\"alternate\" hreflang=\"tr\" href=\"https:\u002F\u002Fafsakar.dev\u002Ftr\u002Fblog\u002Ffirebase-ve-vuejs-ile-kimlik-dogrulama-islemleri\">\n\u003Clink rel=\"alternate\" hreflang=\"x-default\" href=\"https:\u002F\u002Fafsakar.dev\u002Fblog\u002Fauthentication-with-vuejs-and-firebase\">\n\u003Cmeta name=\"robots\" content=\"index, follow\">\n\u003Cmeta property=\"og:title\" content=\"Authentication with Firebase and VueJS\">\n\u003Cmeta property=\"og:description\" content=\"Build Firebase authentication in Vue with Pinia, GitHub login, session-aware route middleware, and protected authenticated and guest pages.\">\n\u003Cmeta property=\"og:type\" content=\"article\">\n\u003Cmeta property=\"og:site_name\" content=\"Azad Furkan Şakar\">\n\u003Cmeta property=\"og:url\" content=\"https:\u002F\u002Fafsakar.dev\u002Fblog\u002Fauthentication-with-vuejs-and-firebase\">\n\u003Cmeta property=\"og:image\" content=\"https:\u002F\u002Fafsakar.dev\u002Fstorage\u002Fog-images\u002Fposts\u002F3-en.png\">\n\u003Cmeta property=\"article:published_time\" content=\"2023-01-14T18:27:06+00:00\">\n\u003Cmeta property=\"article:modified_time\" content=\"2026-08-06T07:27:14+00:00\">\n\u003Cmeta property=\"article:author\" content=\"Azad Furkan Şakar\">\n\n\u003Cmeta name=\"twitter:site\" content=\"afsakar\">\n\u003Cmeta name=\"twitter:card\" content=\"summary_large_image\">\n\u003Cmeta name=\"twitter:image\" content=\"https:\u002F\u002Fafsakar.dev\u002Fstorage\u002Fog-images\u002Fposts\u002F3-en.png\">\n\u003Cmeta name=\"twitter:title\" content=\"Authentication with Firebase and VueJS\">\n\u003Cmeta name=\"twitter:description\" content=\"Build Firebase authentication in Vue with Pinia, GitHub login, session-aware route middleware, and protected authenticated and guest pages.\">\n\u003Cmeta name=\"twitter:url\" content=\"https:\u002F\u002Fafsakar.dev\u002Fblog\u002Fauthentication-with-vuejs-and-firebase\">\n\u003Cscript type=\"application\u002Fld+json\">{\"@context\":\"https:\u002F\u002Fschema.org\",\"@type\":\"Article\",\"name\":\"Authentication with Firebase and VueJS\",\"description\":\"Build Firebase authentication in Vue with Pinia, GitHub login, session-aware route middleware, and protected authenticated and guest pages.\",\"url\":\"https:\u002F\u002Fafsakar.dev\u002Fblog\u002Fauthentication-with-vuejs-and-firebase\",\"image\":\"https:\u002F\u002Fafsakar.dev\u002Fstorage\u002Fog-images\u002Fposts\u002F3-en.png\",\"mainEntityOfPage\":{\"@type\":\"WebPage\",\"@id\":\"https:\u002F\u002Fafsakar.dev\u002Fblog\u002Fauthentication-with-vuejs-and-firebase\"},\"headline\":\"Authentication with Firebase and VueJS\",\"author\":{\"@id\":\"https:\u002F\u002Fafsakar.dev\u002F#person\"},\"publisher\":{\"@id\":\"https:\u002F\u002Fafsakar.dev\u002F#person\"},\"datePublished\":\"2023-01-14T18:27:06+00:00\",\"dateModified\":\"2026-08-06T07:27:14+00:00\"}\u003C\u002Fscript>\u003Cscript type=\"application\u002Fld+json\">{\"@context\":\"https:\u002F\u002Fschema.org\",\"@type\":\"BreadcrumbList\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\u002F\u002Fafsakar.dev\u002F\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\u002F\u002Fafsakar.dev\u002Fblog\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Authentication with Firebase and VueJS\",\"item\":\"https:\u002F\u002Fafsakar.dev\u002Fblog\u002Fauthentication-with-vuejs-and-firebase\"}]}\u003C\u002Fscript>\u003Cscript type=\"application\u002Fld+json\">{\"@context\":\"https:\u002F\u002Fschema.org\",\"@type\":\"Person\",\"name\":\"Azad Furkan Şakar\",\"url\":\"https:\u002F\u002Fafsakar.dev\",\"@id\":\"https:\u002F\u002Fafsakar.dev\u002F#person\",\"jobTitle\":\"Backend Developer\",\"image\":\"https:\u002F\u002Fafsakar.dev\u002Fstorage\u002Fsettings\u002Fseo\u002F01KZB422BTYXF3J7XS1J2X8GYZ.jpeg\",\"sameAs\":[\"https:\u002F\u002Fx.com\u002Fafsakar\",\"https:\u002F\u002Flinkedin.com\u002Fin\u002Fafsakar\",\"https:\u002F\u002Fgithub.com\u002Fafsakar\"]}\u003C\u002Fscript>",{"en":108,"tr":109},"https:\u002F\u002Fafsakar.dev\u002Fblog\u002Fauthentication-with-vuejs-and-firebase","https:\u002F\u002Fafsakar.dev\u002Ftr\u002Fblog\u002Ffirebase-ve-vuejs-ile-kimlik-dogrulama-islemleri",{"type":4,"id":6}]