Where does Firestore Authentication keep user metadata? - firebase-authentication

When using Firestore Authentication, the only fields I see are "Identifier, Providers, Created, Signed In, User UID".
I can call the getAuth() function and get all the data for that user in a React page.
Firebase.js
import { initializeApp, getApps } from 'firebase/app'
import { getAuth } from 'firebase/auth'
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_PUBLIC_API_KEY,
...
}
const firebaseApp = initializeApp(firebaseConfig)
export firebaseApp
What I'm curious about is I can call things like user.displayName but that metadata is not stored on Firebase (at least I don't know where if it is).
MyPage.js
import { firebaseApp } from '../Firebase'
import { getAuth } from 'firebase/auth'
import { useAuthState } from 'react-firebase-hooks/auth'
export default function MyPage() {
const [user, loading, error] = useAuthState(getAuth())
return <h1>Welcome to your account, {user.displayName}!</h1>
}
...
Can anyone please point out where this might be located? I checked Storage in the same GCP project but there wasn't anything there.

Related

Where does the expoClientID go?

I am adding Facebook login to my expo app and it says in the documentation to enter my expoClientId somewhere.
The problem is I cant figure out where to put it. Do I put it in my app.json? Maybe my package.json? In the Facebook developer portal somewhere? Maybe I put it in my expo console somewhere?
Does anyone know where the expoClientId should live? The documentation doesn't say where to put it.
Edit: It looks like I also need to place an iosClientId and an androidClientId as well.
It seems it's a part of the FacebookAuthRequestConfig interface which is used as useAuthRequest() parameter (Expo src).
Turns out you pass it in the request to authorize with facebook like this:
import * as React from 'react';
import * as WebBrowser from 'expo-web-browser';
import * as Facebook from 'expo-auth-session/providers/facebook';
import { ResponseType } from 'expo-auth-session';
import { initializeApp } from 'firebase/app';
import { getAuth, FacebookAuthProvider, signInWithCredential } from 'firebase/auth';
import { Button } from 'react-native';
// Initialize Firebase
initializeApp({
/* Config */
});
WebBrowser.maybeCompleteAuthSession();
export default function App() {
const [request, response, promptAsync] = Facebook.useAuthRequest({
responseType: ResponseType.Token,
clientId: <YOUR FBID>,
expoClientId: <YOUR FBID>, //this is where you add them
iosClientId: <YOUR FBID>,
androidClientId: <YOUR FBID>,
});
React.useEffect(() => {
if (response?.type === 'success') {
const { access_token } = response.params;
const auth = getAuth();
const credential = FacebookAuthProvider.credential(access_token);
// Sign in with the credential from the Facebook user.
signInWithCredential(auth, credential);
}
}, [response]);
return (
<Button
disabled={!request}
title="Login"
onPress={() => {
promptAsync();}}
/>
);
}

pinia store installed after state call

I'm building a vuejs 3 application with composition API.
I have 2 stores: a userStore for holding userid, jwt and similar stuff (that gets populated upon login) and a dataStore that holds data related to the user (populated when user does operations).
When a user logs in successfully, she is redirected to a page containing user data.
The login page uses the userStore and the data page uses the dataStore. The dataStore needs the user's id and jwt.
This method is called upon login:
const submitlogin = async () => {
try {
const response = await postData.post('/user/a/login', {
email: form.email,
password: form.password,
})
if (response) {
userStore.loggedIn = true
// first get the jwt
userStore.getJWT()
// then go to the next page where jwt is required
router.push({
name: 'operation',
params: { sens: 'depense', quand: 'maintenant' },
})
}
} catch (error) {
console.log (error)
}
}
I import the userStore into the dataStore:
// dataStore
import { defineStore } from 'pinia'
import { useUserStore } from '#/stores/userStore.js'
actions: {
async getAccounts(id, month, year) {
const user = useUserStore
// getData is an [axios create function][1]
getData.defaults.headers.common['__authorization__'] = user.jwt
getData.get(`/use/b/comptes/${id}/${month}/${year}`).then((response) => {
// cut because irrelevant here
}
Then, on the first after login:
// data view
import { useUserStore } from '../stores/userStore'
import { useDataStore } from '#/stores/dataStore'
const dataStore = useDataStore()
const userStore = useUserStore()
onMounted(() => {
dataStore.getAccounts()
})
However, the autorization header is undefined only at this first call. If I further navigated to other views where I import the dataStore user.jwt is defined.
It seems that the dataStore is mounted correclty, but its state isn't available yet at the moment I call it.
Solved!
I changed the dataStore so that userStore is defined not within the function, but right after import.
Kind of logical since the getAccounts function is async, so the definition of user.jwt also was.
import { defineStore } from 'pinia'
import { getData } from '#/composables/useApi'
import { sumBy } from 'lodash'
import { useUserStore } from '#/stores/userStore.js'
// put this here, not within the async action !
const userStore = useUserStore()
actions: {
async getAccounts(id, month, year) {
getData.defaults.headers.common['__authorization__'] = userStore.jwt
getData.get(`/use/b/comptes/${id}/${month}/${year}`).then((response) => {
// cut because irrelevant here
}

redux-persist/createPersistoid: error serializing state TypeError: Converting circular structure to JSON

I am trying to integrate redux-persist to my react-native project. The aim is to persist the redux store's data between application re-launch so that user does not need to log in each time they launch the app. Also, I want to store the previously viewed data on the local storage to avoid re-querying all the data each time app is re-launched.
I added the redux persist support as per the code below:
import { AsyncStorage } from 'react-native';
import { createStore, applyMiddleware } from 'redux';
//import { createLogger } from 'redux-logger';
import { persistStore, persistReducer } from 'redux-persist';
import rootReducer from '../reducers/index';
import ReduxThunk from 'redux-thunk';
import { createTransform } from 'redux-persist';
import JSOG from 'jsog';
export const JSOGTransform = createTransform(
(inboundState, key) => JSOG.encode(inboundState),
(outboundState, key) => JSOG.decode(outboundState),
)
const persistConfig = {
// Root
key: 'root',
// Storage Method (React Native)
storage: AsyncStorage,
//transforms: [JSOGTransform]
// Whitelist (Save Specific Reducers)
// whitelist: [
// 'authReducer',
// ],
// // Blacklist (Don't Save Specific Reducers)
// blacklist: [
// 'counterReducer',
// ],
};
// Middleware: Redux Persist Persisted Reducer
const persistedReducer = persistReducer(persistConfig, rootReducer);
// Redux: Store
const store = createStore(
persistedReducer,
applyMiddleware(ReduxThunk),
);
// Middleware: Redux Persist Persister
let persistor = persistStore(store);
// Exports
export {
store,
persistor,
};
If I don't add jsog and use the transforms: [JSOGTransform] line in the persistConfig I get this error:
redux-persist/createPersistoid: error serializing state TypeError:
Converting circular structure to JSON
If I uncomment the 'transforms' line in the persistConfig (as per the suggestion here: https://github.com/rt2zz/redux-persist/issues/735), then I get this error:
Exception in HostObject::set: < unknown >
I am just persisting the returned "user" object from the firestore database in my redux-store. Without the redux-persist, there has been no problem, but with the persist added I am having this issue.
What type of circular problem would exist in the user object returned after successful login to firestore (using password/email auth.)?
Why would JSOG not work as suggested in the link above? Any alternatives to how I can solve this problem?
P.S. Not only the user returned from firestore is causing these errors, but any data returned from firestore seems to fail to persist.
I appreciate any helps!
Cheers...
I think I solved the problem. Instead of JSOG I installed flatted and used in for my redux-persist transform.
Working transform and persistConfig looks like this:
export const transformCircular = createTransform(
(inboundState, key) => Flatted.stringify(inboundState),
(outboundState, key) => Flatted.parse(outboundState),
)
const persistConfig = {
key: 'root',
storage: AsyncStorage,
stateReconciler: autoMergeLevel2,
transforms: [transformCircular]
};
Some developer have this problem because of the socket set in Redax, Otherwise, you can use this way as well
// SetTransform.js
import { createTransform } from 'redux-persist';
const SetTransform = createTransform(
// transform state on its way to being serialized and persisted.
(inboundState, key) => {
// convert mySet to an Array.
return { ...inboundState, mySet: [...inboundState.mySet] };
},
// transform state being rehydrated
(outboundState, key) => {
// convert mySet back to a Set.
return { ...outboundState, mySet: new Set(outboundState.mySet) };
},
// define which reducers this transform gets called for.
{ whitelist: ['someReducer'] }
);
export default SetTransform;
and
// PersistReducers
import storage from 'redux-persist/lib/storage';
import { SetTransform } from './transforms';
const persistConfig = {
key: 'root',
storage: storage,
transforms: [SetTransform]
};

How to get the device token in react native

I am using react-native 0.49.3 version, My Question is how to get the device token in react native for both IOS and Android I tried with this link but it not working for me, right now I tried in IOS. how to resolve it can one tell me how to configure?
I tried different solutions and I've decided to use React Native Firebase.
Here you will find everything about Notifications.
Also, you can use the others libraries that come with Firebase, like Analytics and Crash Reporting
After set up the library you can do something like:
// utils/firebase.js
import RNFirebase from 'react-native-firebase';
const configurationOptions = {
debug: true,
promptOnMissingPlayServices: true
}
const firebase = RNFirebase.initializeApp(configurationOptions)
export default firebase
// App.js
import React, { Component } from 'react';
import { Platform, View, AsyncStorage } from 'react-native';
// I am using Device info
import DeviceInfo from 'react-native-device-info';
import firebase from './utils/firebase';
class App extends Component {
componentDidMount = () => {
var language = DeviceInfo.getDeviceLocale();
firebase.messaging().getToken().then((token) => {
this._onChangeToken(token, language)
});
firebase.messaging().onTokenRefresh((token) => {
this._onChangeToken(token, language)
});
}
_onChangeToken = (token, language) => {
var data = {
'device_token': token,
'device_type': Platform.OS,
'device_language': language
};
this._loadDeviceInfo(data).done();
}
_loadDeviceInfo = async (deviceData) => {
// load the data in 'local storage'.
// this value will be used by login and register components.
var value = JSON.stringify(deviceData);
try {
await AsyncStorage.setItem(config.DEVICE_STORAGE_KEY, value);
} catch (error) {
console.log(error);
}
};
render() {
...
}
}
Then you can call the server with the token and all the info that you need.

Got An Error: firestore.setListeners is not a function. while integrating redux-firestore with react-redux-firebase#2.0.*

Blockquote
PHOTO(Click here to see the Error) : Got An Error: firestore.setListeners is not a function
Blockquote
I have just integrated redux-saga, redux-firestore with react-redux-firebase#2.. and its working fine but when i try to integrate with other COMPONENT i got This Error..
ANY SOLUTION!!
THANKS
This is the error white integrating redux-firestore with react-reduc-firebase
Code:
import { compose } from 'redux'
import { connect } from 'react-redux'
// import { getFirestore } from 'redux-firestore';
import {
firestoreConnect,
createWithFirebase,
withFirebase,
firebaseConnect
} from 'react-redux-firebase'
*******
**etc**
*******
// export default Inventory;
export default compose(
// firestoreConnect([{collection: 'Invetory'}]),
firebaseConnect(),
connect(
({ firestore }) => ({
//todos: firestore.ordered.todos,
firestore
})
)
// connect((state) => ({
// auth: state.firestore.auth
// })
)(Inventory)
Author of react-redux-firebase here.
Looks like you may not have included importing Firestore as mentioned in the Firestore section of the react-redux-firebase docs. Make sure you include the enhancer, the reducer, and import firestore from Firebase like so:
import { createStore, combineReducers, compose } from 'redux'
import firebase from 'firebase'
import 'firebase/firestore' // add this to use Firestore
import { reactReduxFirebase, firebaseReducer } from 'react-redux-firebase'
import { reduxFirestore, firestoreReducer } from 'redux-firestore'
const firebaseConfig = {}
// react-redux-firebase config
const rrfConfig = {
userProfile: 'users',
// useFirestoreForProfile: true // Firestore for Profile instead of Realtime DB
}
// initialize firebase instance
firebase.initializeApp(firebaseConfig) // <- new to v2.*.*
// initialize Firestore
firebase.firestore()
// Add reduxReduxFirebase and reduxFirestore enhancers when making store creator
const createStoreWithFirebase = compose(
reactReduxFirebase(firebase, rrfConfig),
reduxFirestore(firebase)
)(createStore)
// Add Firebase and Firestore to reducers
const rootReducer = combineReducers({
firebase: firebaseStateReducer,
firestore: firestoreReducer
})
// Create store with reducers and initial state
const initialState = {}
const store = createStoreWithFirebase(rootReducer, initialState)