How can I get loggedin status of a user when using Authenticator component of Amplify UI - aws-amplify

The vue control has the following code:
The user is logged in but the route is displayed as null. Any suggestions on what I am doing wrong.
<script setup>
// import { Amplify} from "aws-amplify";
// import awsconfig from "#/aws-exports";
import { Authenticator, useAuthenticator } from '#aws-amplify/ui-vue';
import { mapMutations, mapState} from "vuex"
// Amplify.configure(awsconfig);
const auth = useAuthenticator();
console.log("navbar: ", auth.route);
</script>

Related

Implement getSession() in NextJS 13

I implemented nextAuth in my app and faced a glitch problem on UI, when the page is reloaded I can see Signed in as ../ Not signed in for a second till a new session is fetched. I found the solution of this problem for NextJS 12 and older, and I have some difficulties to implement it in NextJS 13 without getServerSideProps().
'use client'
import './globals.css'
import { getSession, SessionProvider } from 'next-auth/react'
export default function RootLayout({ session, children }) {
return (
<html lang="en">
<head />
<body>
<SessionProvider session={session}>
{children}
</SessionProvider>
</body>
</html>
)
}
How to implement this function for the code above?
export async function getServerSideProps(ctx) {
return {
props: {
session: await getSession(ctx)
}
}
}
Source: https://stackoverflow.com/a/68942471/4655668
getServerSession : When calling from server-side i.e. in API routes or in getServerSideProps, we recommend using this function instead of getSession to retrieve the session object. This method is especially useful when you are using NextAuth.js with a database.
import { authOptions } from 'pages/api/auth/[...nextauth]'
import { getServerSession } from "next-auth/next"
export async function getServerSideProps(context) {
const session = await getServerSession(context.req, context.res, authOptions)
//...
}

Vue3 Pinia store not loading until vue devtools is launched

I encounter a strange behavior with pinia in a Vue3 app.
I created a little app with a pinia store using option API.
Here is my main.js with creating the store :
import { createApp } from "vue";
import { createPinia } from "pinia";
// Vue Router
import index from "./router";
// import { useAspergesStore } from "./store/storeAsperges";
import App from "~/App.vue";
import "~/styles/tailwind.css";
import "~/styles/main.scss";
const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
app.use(index);
app.mount("#app");
Here is my store :
import { defineStore } from 'pinia'
import axios from "axios";
export const useAspergesStore = defineStore('asperges', {
state: () => ({
listeCueilleurs: JSON.parse(localStorage.getItem("listeCueilleurs")) || [],
}),
getters: {
...
},
actions: {
...
},
})
And I call the store from my components :
import { useAspergesStore } from '../../../store/storeAsperges.js';
import { mapStores } from 'pinia';
...
computed: {
...mapStores(useAspergesStore),
},
When I start the web page, I can't get the datas from the store, even on a reload. The store is not loaded.
When I open the devTools in chrome, it doesn't show that the store is loaded.
When I click on the vueDevTools, the store loads and the datas appear in the web page.
I get the message in the console :
"🍍 "asperges" store installed 🆕"
It's like starting the vueDevTools triggers the store. And all work fine after that.
If you have any idea of what I'm doing wrong, any help would be appreciated.
Ok I found a solution. I don't know if it's the right one, but it works.
I just tried to call the store from the component in the mounted() hook and now the store loads correctly.
But anyway, I don't know why the store didn't load even if the datas were used in the components...

Handle 401 error in react-redux app using apisauce

The problem: i have many sagas that do not handle an 401 error in response status, and now i have to deal with it. I have apiservice based on apisause and i can write an response monitor with it to handle 401 error (like interceptors in axios). But i cant dispatch any action to store to reset user data, for example, because there is no store context in apiservice. How to use dispatch function in apiservice layer? Or use put() function in every saga when i recieve 401 response status is the only right way?
you can use refs for using navigation in 'apisauce' interceptors
this is my code and it works for me ;)
-- packages versions
#react-navigation/native: ^6.0.6
#react-navigation/native-stack: ^6.2.5
apisauce: ^2.1.1
react: 17.0.2
react-native: ^0.66.3
I have a main file for create apisauce
// file _api.js :
export const baseURL = 'APP_BASE_URL';
import { create } from 'apisauce'
import { setAPIInterceptors } from './interceptors';
const APIClient = create({ baseURL: baseURL })
setAPIInterceptors(APIClient)
and is file interceptors.js I'm watching on responses and manage them:
// file interceptors.js
import { logout } from "../redux/actions";
import { store } from '../redux/store';
import AsyncStorage from '#react-native-async-storage/async-storage';
export const setAPIInterceptors = (APIClient) => {
APIClient.addMonitor(monitor => {
// ...
// error Unauthorized
if(monitor.status === 401) {
store.dispatch(logout())
AsyncStorage.clear().then((res) => {
RootNavigation.navigate('login');
})
}
})
}
then I create another file and named to 'RootNavigation.js' and create a ref from react-native-navigation:
// file RootNavigation.js
import { createNavigationContainerRef } from '#react-navigation/native';
export const navigationRef = createNavigationContainerRef()
export function navigate(name, params) {
if (navigationRef.isReady()) {
navigationRef.replace(name, params);
}
}
// add other navigation functions that you need and export them
then you should to set some changes in you App.js file:
import { NavigationContainer } from '#react-navigation/native';
import { navigationRef } from './RootNavigation';
export default function App() {
return (
<NavigationContainer ref={navigationRef}>{/* ... */}</NavigationContainer>
);
}
finally in anywhere you can call this function for use react native navigations
full focument is in here that explain how to Navigating without the navigation prop
Navigating without the navigation prop

I'm trying to create an app using Framework-7 Vuejs. I want to make my user stay logged in even after exiting the app using Firebase

I want to add Firebase's code in my Framework-7 Vue.js app. So that a user can stay logged in even arter exiting the app.
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
store.commit(setSignedIn, true)
} else {
store.commit(setSignedIn, false)
}
});
I need to add this in my app.js of my project:
// Import Vue
import { createApp } from 'vue';
// Import Framework7
import Framework7 from 'framework7/lite-bundle';
// Import Framework7-Vue Plugin
import Framework7Vue, { registerComponents } from 'framework7-vue/bundle';
// Import Framework7 Styles
import 'framework7/framework7-bundle.css';
// Import Icons and App Custom Styles
import '../css/icons.css';
import '../css/app.css';
// Import App Component
import App from '../components/app.vue';
import store from '../pages/store/store';
// Init Framework7-Vue Plugin
Framework7.use(Framework7Vue);
// Init App
const app = createApp(App);
app.use(store)
// Register Framework7 Vue components
registerComponents(app);
// Mount the app
app.mount('#app');
Can someone please help me to do this. Thanks
I am using Vuex Persisted State package for such purposes. It is quite simple to add. Try it out.
With Vuex Persisted State your Vuex store will be stored in localStorage so the user won't be logged out after exiting the app.

Framework7, Firebase, VueJS Routes RequireAuth

This is my main.js
import Vue from 'vue';
import Framework7 from 'framework7/dist/js/framework7.js';
import Framework7Vue from 'framework7-vue/dist/framework7-vue.js';
import Routes from './routes.js';
import App from './app.vue';
import * as firebase from 'firebase';
Vue.use(Framework7Vue, Framework7);
var config = {
};
firebase.initializeApp(config);
new Vue({
el: '#app',
template: '<app/>',
framework7: {
id: 'io.framework7.testapp',
name: 'Framework7',
theme: 'auto',
routes: Routes,
},
components: {
app: App
}
});
console.log(Routes)
Routes.beforeEach((to, from, next) => {
// let currentUser = firebase.auth().currentUser;
console.log()
})
I tried for a few hours now to implement that a user needs to be Authenticated before he can enter the Home View. Otherwise he will be redirected to the login View.
Maybe anyone can help me.
The following changes to your main.js file should normally do the trick. (I don't know however, if the framework7 framework interacts with the router and may cause problems).
You use router.beforeEach() to check if the "target" needs the user to be authenticated (based on requiresAuth meta). If the user is not authenticated you need to redirect her/him to the signin page. For that you can use firebase.auth().currentUser. See the corresponding Firebase doc here.
import Vue from 'vue';
import VueRouter from 'vue-router';
import Framework7 from 'framework7/dist/js/framework7.js';
import Framework7Vue from 'framework7-vue/dist/framework7-vue.js';
import Routes from './routes.js';
import App from './app.vue';
import * as firebase from 'firebase';
Vue.use(Framework7Vue, Framework7);
Vue.use(VueRouter);
var config = {
};
firebase.initializeApp(config);
const router = new VueRouter({
Routes,
mode: 'history'
});
router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
const currentUser = firebase.auth().currentUser
if (requiresAuth && !currentUser) {
next('/signin')
} else if (requiresAuth && currentUser) {
next()
} else {
next()
}
})
new Vue({
el: '#app',
template: '<app/>',
framework7: {
id: 'io.framework7.testapp',
name: 'Framework7',
theme: 'auto',
routes: VueRouter,
},
components: {
app: App
}
});
I don't know anything about Vue Router but the firebase way to do this is to wait for onAuthStateChanged method to trigger and track user state with this function.
To wait and get user state, i wrote a piece of code that you can call before changing route.
var user, authPromiseResolver, authPromiseResolved
var authPromise = new Promise(function(resolve, reject){
authPromiseResolver = resolve
})
var waitForUser = function(){
return new Promise(function(resolve, reject){
if(!authPromiseResolved){
authPromise.then(resolve)
} else {
resolve(user)
}
})
}
firebaseApp.auth().onAuthStateChanged(function(firebaseUser) {
user = firebaseUser
if(!authPromiseResolved){
authPromiseResolver(user)
authPromiseResolved = true
}
})
waitForUser returns a promise who wait for first trigger of onAuthStateChanged (which will determine if an user is already logged in or not at page refresh), then resolve with user data or null it no user is logged in. So you just have to call this function before accessing each page :
waitForUser().then(function(user){
if(user) {
// An user is logged in
} else {
// Page unauthorized
}
})
Each time the user state change (user logout/login), user variable will be set to null or with firebaseUser object and waitForUser() will always be resolved with the current user state

Resources