authentication
Consider a stripped down representation of two functions that live inside ioa's top-level context. ioa values a fully isolated authentication process which creates a redeemable session available when revisiting an app.
A special listener, onAuthStateChanged()
, inside the app's highest level context provider is tasked with handling all changes to the listener's callback, user
. It's responsive to a set of well-defined auth state changes, e.g., user chooses to identify with Google or chooses to identify with GitHub, etc.
The following snippet is a representation of ioa initialization.
// src/SessionProvider.js
. . .
componentDidMount() {
. . .
const unsubscribe = firebase.auth()
.onAuthStateChanged(async user => {
if (user != null) {
const { providerData, ...rest } = user;
. . .
if (userConfig) {
// initialize with existing user
this.initializeApp();
} else {
// initialize with newly-created config fetched from cloud
const payload = await api.createNewUser();
this.initializeApp(payload);
}
} else {
firebase.auth().signOut();
}
});
};
. . .
Here is a representation of setting the state inside ioa's Provider. Note that all listeners are set by the callback of setState()
to conclude the Provider's lifecycle.
Please know that very strict measures are taken in an attempt to limit ioa to only one state change per component.
// src/SessionProvider.js
initializeApp = async () => {
. . .
// insert sequence of "blocked" async reduction building initial state
// memoization?
this.setState({}, () => {
// please note these conditions throughout the app.
// please practice building idempontent operations
if (user) this.setListeners();
if (user) this.initNotifications();
});
};