JS, React & React Native

Insérer des données dans Firestore

April 29, 2020

Dans cet article, nous allons continuer la petite application que nous avons commencée la semaine dernière.

Nous avions déjà commencé par créer l’affichage permettant d’afficher les tâches de notre liste de tâches. Nous allons maintenant créer un petit formulaire qui nous permettra d’ajouter des tâches et de les enregistrer sous Firestore.

Pour continuer, on va reprendre l’application depuis là on nous en étions la semaine dernière. Vous pouvez récupérer le code sur Github: https://github.com/nico91470/taskyBlog

La branche Master contient la version de la semaine dernière. Si vous souhaitez avoir directement le code de cette semaine, il est disponible dans la branche “AddDataFirestore”.

Modification de la page d’accueil

Sur la page d’accueil, nous allons ajouter une fenêtre modale qui va afficher le formulaire.

Pour commencer, nos allons modifier la première ligne pour utiliser les states au sur App.js

import React, { useState } from 'react'

On va ensuite définir un “state” pour savoir si la fenêtre modale est ouverte ou non. Par défaut, elle sera invisible.

const [modalVisible, setModalVisible] = useState(false)

Ajout du bouton d’ouverture de la modale

On ajoute ensuite un bouton qui nous permettra d’ouvrir la modale en mettant à jour la propriété “visible” de celle-ci.

Pour ajouter ce bouton, nous allons utiliser un icône que nous pouvons trouver dans la bibliothèque: https://expo.github.io/vector-icons/

Ce site contient énormément d’icones que vous pouvez utiliser dans vos applications. J’ai toujours trouvé un icône qui correspond à mes besoins.

On fait l’import de celle-ci en début de fichier:

import { Octicons } from '@expo/vector-icons'

Et ensuite, on l’ajoute sur la page d’accueil:

<Octicons
    name={'diff-added'}
    size={40}
    onPress={() => setModalVisible(true)}
/>

Ajout du bouton de fermeture de la modale

Maintenant, on ajoute le code de la modale:

    <Modal visible={modalVisible} animationType='slide'>
        <View>
        <Octicons >
        <Text>Affichage Modal</Text>
        </View>
    </Modal>

Sans oublier bien sûr de mettre à jour nos imports

import { Text, View, StyleSheet, Modal } from 'react-native';

Si vous lancez l’application maintenant, vous pourrez voir la modale s’ouvrir. Le seul petit problème, c’est que nous ne pouvons pas la fermer. On va donc faire comme pour la fenêtre principal et ajouter un bouton avec un petit icône dedans qui va nous permettre de la fermer

    <Modal visible={modalVisible} animationType='slide'>
        <View>
        <Octicons
            name={'x'}
            size={40}
            style={styles.buttonStyle}
            onPress={() => setModalVisible(false)}
        />
        <Text>Affichage Modal</Text>
        </View>
    </Modal>

Création du composant contenant le formulaire

Pour pouvoir enregistrer la nouvelle tâche, nous allons créer un formulaire qui contient un champs pour écrire la tâche et un bouton pour enregistrer.

On va donc créer un nouveau fichier ‘AddTodo.js’ dans le répertoire “components”. Ce composant contient un TextInput et un bouton que nous aurons récupérer cette fois-ci dans la bibliothèque MaterialIcons.

import React, { useState } from 'react'
import { View, TextInput, StyleSheet } from 'react-native'
import { MaterialIcons } from '@expo/vector-icons'

export default function AddTodo({ addTodo }) {

    const [tache, setTache] = useState('')
    return (
        <View>
            <TextInput
                placeholder='Saisir la nouvelle tâche'
                onChangeText={(text) => setTache(text)}
                style={styles.textInput}
                value={tache}
            />
            <MaterialIcons
                name={'save'}
                size={40}
                style={styles.buttonStyle}
                onPress={() => addTodo(tache)}
            />
        </View>
    )
}

const styles = StyleSheet.create({
    buttonStyle: {
        alignSelf: 'center',
        margin: 10
    },
    textInput: {
        borderWidth: 1,
        borderColor: '#ddd',
        padding: 10,
        margin: 5,
        fontSize: 18,
        borderRadius: 6,
    }
})

La première chose dans ce code est que nous avons ajouté une props “addTodo” que nous n’avons pas encore définie. Elle le sera dans la prochaine partie, dans le fichier “App.js”. Ensuite, on reste dans le classique avec l’utilisation du “useState” pour stocker le contenu de notre champs.

Et pour rendre ça un poil plus joli, on applique un petit style.

On finit dans le fichier “App.js” justement, en ajoutant le nouveau composant et en n’oubliant pas de définir notre “props”.

    <Modal visible={modalVisible} animationType='slide'>
        <View>
        <Octicons
            name={'x'}
            size={40}
            style={styles.buttonStyle}
            onPress={() => setModalVisible(false)}
        />
        <AddTodo addData={addTodo} />
        </View>
    </Modal>

Ajout de la fonction d’enregistrement

Pour l’ajout de l’enregistrement, on va commencer par modifier le fichier “firebase.js” afin d’ajouter la fonction d’enregistrement:

import * as firebase from 'firebase'
import 'firebase/firestore'

import firebaseConfig from './config'

firebase.initializeApp(firebaseConfig)

const db = firebase.firestore()

const Firebase = {
    todos: () => {
        return db.collection('todos')
    },
    addTodos: (tache) => {
        return db.collection('todos').add({ tache })
    }
}

export default Firebase

Pour terminer, il ne reste plus qu’à définir notre fonction addTodo dans le fichier “App.js”

  const addTodo = (tache) => {
    Firebase.addTodos(tache)
    setModalVisible(false)
  }

On fait l’appel à notre nouvelle fonction et ensuite, on n’oublie pas de fermer la modale pour revenir sur l’écran d’accueil. Avec ce que nous avons fait la semaine dernière, la page d’accueil se recharge automatiquement.

Petit bonus

Comment l’écran d’accueil était vraiment moche, j’ai ajouté un petit peu de CSS dans le fichier “Todo.js”

import React from 'react'
import { StyleSheet, View, Text } from 'react-native'

export default function Todo({ todo }) {

    return (
        <View>
            <Text style={styles.text}>{todo}</Text>
        </View>
    )
}

const styles = StyleSheet.create({
    text: {
        padding: 5,
        fontSize: 15,
        textAlign: 'center'
    }
})