Attention, cet article n'est pas à jour.
Avec React, vous savez persister les données de l'utilisateur, mais une nouvelle question se pose. Comment en partager une partie avec les autres utilisateurs? Dans le cadre d'un tchat par exemple?
C'est ce que nous allons voir en utilisant firebase.
Attention : un minimum de connaissances sur React est requis. Si vous ne connaissez pas encore React, c'est par ici que cela se passe : feuille-de-route-react :)
1. Firebase
Firebase est un outil qui fournit plusieurs services (authentification, base de données etc..). Ici nous allons nous intéresser au real-time database qui s'accorde parfaitement avec le concept de state de React :).
1.1. Configuration
Note : Si vous voulez passez cette étape (ne pas avoir votre propre compte Firebase), vous pouvez utiliser les informations contenues dans la section 1.2.
Dans un premier temps, allons sur la page d'accueil de Firebase est connectons nous avec un compte google.
Une fois cela fait, rendez-vous dans la console afin de créer le projet.
Maintenant que le projet est créé, il nous faut encore modifier les règles d'accès à la base de données, car, pour l'instant, celle-ci n'est accessible que lorsque l'utilisateur est authentifié, or nous n'avons pas besoin. Il nous faut donc modifier ces règles comme ceci :
Et la configuration est fini !
1.2. Récupération des informations de connexion
Cliquez sur l'onglet "Overview" du menu gauche afin d'accéder à l'icône "Ajouter firebase à votre application web". Cliquez sur celle-ci, puis, dans la fenêtre qui apparaît copiez la variable config, nous en aurons besoin plus tard.
Note : Vous pouvez utiliser mes informations, on pourra avoir le même tchat comme cela :D.
2. React
Maintenant que nous avons notre base de données, configurons notre application React afin de la synchroniser avec Firebase.
2.1. Installation du projet
Note: J'utilise ici yarn, qui est, dans l'ensemble, plus rapide que npm. Si vous voulez utiliser npm, voici une page listant les correspondances entre les commandes yarn que je vais utiliser et celle de npm : http://ricostacruz.com/cheatsheets/yarn.html.
Récupérons donc le projet react-chat-without-firebase que j'ai créé pour vous :
$ git clone https://github.com/gkueny/react-chat-without-firebase.git react-chat-with-firebase
$ cd react-chat-with-firebase
$ yarn
Afin d'utiliser firebase, nous allons également avoir besoin du package npm firebase. Ajoutons celui-ci à notre projet. (Et bien sûre, on n'oublie pas de lancer notre serveur ;) ).
$ yarn add firebase
$ yarn start
2.2. Mettons en place firebase
Bon... Là on a un beau tchat, mais il n'y a qu'un seul utilisateur possible. En plus si on supprime le state enregistré, pouf les messages disparaissent.
a. Connexion à firebase
Pour se connecter à notre base de données Firebase, nous allons utiliser notre variable config :
// File : src/index.js [EXTRAIT]
//...
import * as firebase from "firebase";
//...
// On retrouve notre variable config ;)
// Remplacez par la votre si vous voulez
const config = {
apiKey: "AIzaSyA5pPKO8J9sR1m3hyPu7WJw2MzIu0z0q6o",
authDomain: "react-tchat-e518d.firebaseapp.com",
databaseURL: "https://react-tchat-e518d.firebaseio.com",
storageBucket: "react-tchat-e518d.appspot.com",
messagingSenderId: "640840838780"
};
firebase.initializeApp(config);
//...
b. Synchronisation avec firebase
Dans un premier temps, modifions la façon de gérer les messages. Nous allons les récupérer par Firebase. Du coup, au lieu de mettre à jour notre variable messages en y concaténant le nouveau message, nous allons la remplacer à chaque fois par les messages reçus de Firebase. Ce qui donne :
// File : src/actions/chat.actions.js
import { UPDATEMESSAGES } from "./actions.type";
export function updateMessage(messages) {
return {
type: UPDATEMESSAGES,
data: {
messages
}
};
}
// File : src/reducers/chat.reducer.js [EXTRAIT]
//..
const chatReducer = (state = initialState, action) => {
switch (action.type) {
case UPDATEMESSAGES: {
return {
...state,
messages: action.data.messages
};
}
//..
}
};
export default chatReducer;
// File : src/containers/chat.container.js [EXTRAIT]
//..
const mapDispatchToProps = dispatch => {
return {
updateMessage: messages => dispatch(updateMessage(messages))
};
};
//...
Nous avons notre partie Redux prête pour la synchronisation avec Firebase. Maintenant il nous faut récupérer une référence à notre nouvelle base de données :
// File : src/components/chat.component.js [EXTRAIT]
import * as firebase from "firebase";
//..
class ChatComponent extends Component {
constructor(props) {
super(props);
const rootRef = firebase.database().ref();
this.messagesRef = rootRef.child("messages");
this.state = {
messageWriting: ""
};
}
//...
}
//...
Mais attends... On récupère une référence vers "l'enfant" "messages" ? on ne l'a jamais créé dans Firebase non ?
Pas de souci ! Si "messages" n'existe pas, Firebase le créera.
Avec cette référence, nous allons pouvoir créer un listener qui sera appelé à chaque fois qu'un nouveau message est ajouté à Firebase :
// Fichier : src/components/chat.component.js [EXTRAIT]
//..
componentDidMount() {
// notre listener
this.messagesRef.on('value', snapshot => {
let messages;
// les valeurs de la base de données sont récupérables via snapshot.val()
// On récupère ces données sous la forme [index] = value
messages = snapshot.val() ? Object.keys(snapshot.val()).map( key => {
return snapshot.val()[key];
}) :
messages = [];
// On met à jour notre state à partir des messages récupérés de Firebase
this.props.updateMessage(messages);
});
}
// Et on supprime le listener lorsque le composant est détruit
componentWillUnmount() {
this.messagesRef.on('value').off();
}
//..
Allez, dernière étape ! Envoyons notre nouveau message à Firebase :
// Fichier : src/components/chat.component.js [EXTRAIT]
//..
sendNewMessage = e => {
e.preventDefault();
// On ajoute une nouvelle entrée dans notre base de données et on récupère la clé correspondante
const newMessageKey = this.messagesRef.push().key;
// On décrit notre nouvelle entrée
let updates = {};
updates["/messages/" + newMessageKey] = {
name: this.props.name,
text: this.state.messageWriting
};
// On met à jour
firebase
.database()
.ref()
.update(updates);
this.setState({
messageWriting: ""
});
};
//..
Plus besoin de mettre à jour notre state, car notre ajout entrainera l'appel de notre listener :D.
Finis ! Maintenant, nos messages sont synchronisés avec Firebase et ainsi tout les utilisateurs possèdent les mêmes messages.