In-Class exercise: Using Firestore

Our goal in this exercise is to make the People application work with Firestore.
  1. We'll be using the following GitHub project:
    1. If you haven't yet already cloned that project, follow the instructions.
    2. If you have already cloned that project:
      1. Pull the latest changes (git pull from terminal, or Git/Pull... menu from WebStorm).
      2. Checkout the specified branch above
  2. Update the project to specify that it depends on firebase and the react-firebase-hooks projects.
  3. Add firestore initialization to App.js (note that this initialization will refer to a firestore project that I've created solely for this exercise):
    import { initializeApp } from "firebase/app";
    import { getFirestore } from "firebase/firestore";
    
    const firebaseConfig = {
        apiKey: "AIzaSyCYhMdciPP9F9Gs38fUEHnOP_C63RwkDFo",
        authDomain: "cs124-firestore-impl-exercise.firebaseapp.com",
        projectId: "cs124-firestore-impl-exercise",
        storageBucket: "cs124-firestore-impl-exercise.appspot.com",
        messagingSenderId: "492659596453",
        appId: "1:492659596453:web:fa8ea46ba19f37c0fa414c"
    };
    
    const firebaseApp = initializeApp(firebaseConfig);
    const db = getFirestore(firebaseApp);
    
  4. Currently, the People app uses in-memory data. Remove the use of that data:
    1. Remove the definition of initialData and remove the call to useState.
    2. Comment-out all use of people and setPeople in App.
  5. Add support for Firestore:
    1. Determine which collection name you'll use.

      Each team should use a different collection name. Use the name People-section-team (where section is either 1 or 2 and where team is one of 2, 3, 4, 5 6, 7, 8, 9, T, J, Q, K, A) depending on which card pair you were randomized with. As an example, the group in section 1 that got queens would use the collection name "people-1-Q".

      Hint: declare a constant in App.js containing your collection name. If you run into problems with your collection, feel free to create another empty collection with a similar name (perhaps People2-section-team)

    2. In App, call useCollectionData with a query that'll retrieve all documents from your collection.
      const q = ...;    // Fill in query here
      const [people, loading, error] = useCollectionData(q);
      
    3. If loading is true, display a loading message (and don't display the People component).
    4. Pass in the array of people objects as the value of the people attribute to the People component.
    5. Run your app and verify that:
      • The loading message initially displays, then
      • an empty list of people is shown.
    6. Implement handleAddPerson to add a new empty person to Firestore.

      Hint: use setDoc().

      Test to ensure you can create new (empty) people.

    7. Implement handleChangeField to modify the field of a person in Firestore.

      Hint: use updateDoc().

      Test to ensure you can edit people.

    8. Implement handleDeleteSelected to delete the selected people from Firestore.

      Hint: use deleteDoc.

      Test to ensure you can delete people.

    9. Open the People app in two different windows and verify that updates are automatically propagated from one window to the other.

      What happens programatically in the People application in window A when a change is made in window B?

  6. Challenge: Add the ability to sort by name (ascending or descending) and sort by email (ascending or descending). Modify the Firestore query to do the sorting rather than trying to sort in JavaScript.

    Make sure the UI for this functionality is designed well.