Luka Miljković
Luka Miljković

Reputation: 126

How to set a custom ID of a nested array object in Firebase?

I'm trying to implement an edit and add comment function to my todo app. Currently, every user has it's own todos in an array.

enter image description here

Is it possible to generate or set a custom index value for every todo in the 'todos' array so I can tell which todo I want to change or for which todo I want to add a new comment? I already have templates for thoes functions, since the previous version of the app didn't have user specific todos.

This is the code for when the user is created:

const addUser = async (username, userid) => {
        const docRef = doc(db, "users", userid);
        const docSnap = await getDoc(docRef);
        if (docSnap.exists()) {
            console.log("Document data:", docSnap.data());
        } else {
            await setDoc(doc(db, 'users', userid), {
                name: username,
                todos: {}
            })
        }
    }

    //sign up with google popup
    const signInWithGoogle = async () => {
        signInWithPopup(auth, provider).then(result => {
            const username = result.user.displayName;
            const userId = result.user.uid;
            navigate('/todos');
            addUser(username, userId);
        }).catch(err => {
            console.log(err);
        })
    }

And this the code for creating new todos:

const addTodo = async () => {
        const userRef = doc(db, "users", user.uid);
        var date = new Date(todoDate);
        var dd = date.getDate();

        var mm = date.getMonth() + 1;
        var y = date.getFullYear();

        var h = date.getHours();
        var min = date.getMinutes();

        if (dd < 10) {
            dd = '0' + dd;
        }

        if (mm < 10) {
            mm = '0' + mm;
        }

        if (h < 10) {
            h = '0' + h;
        }

        if (min < 10) {
            min = '0' + min;
        }
        date = mm + '-' + dd + '-' + y + " " + h + ":" + min;

        var date2 = new Date();
        var dd = date2.getDate();

        var mm = date2.getMonth() + 1;
        var y = date2.getFullYear();

        var h = date2.getHours();
        var min = date2.getMinutes();

        if (dd < 10) {
            dd = '0' + dd;
        }

        if (mm < 10) {
            mm = '0' + mm;
        }

        if (h < 10) {
            h = '0' + h;
        }

        if (min < 10) {
            min = '0' + min;
        }
        date2 = mm + '-' + dd + '-' + y + " " + h + ":" + min;

        //create a new todo instance
        const todo = {
            text: todoName,
            addedBy: user.displayName || user.email,
            userPic: user.photoURL,
            dueDate: date,
            createdOn: date2,
            comments: [],
            importance: importance
        }

        await updateDoc(userRef, {
            //push the new todo in the currently active user's todo array
            todos: arrayUnion(todo)
        });
        window.location.reload();
    }

Upvotes: 0

Views: 363

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 599551

There is no way to update an existing item in an array field in Firestore.

You'll have to:

  1. Read the document from the database and get the current value of the array field from it.
  2. Update the array field in your application code.
  3. Write the entire array field back to the database.

This has been covered (quite) a few times already, so I recommend also checking out some of these search results.

Upvotes: 1

Related Questions