How to add documents to firestore from Nextjs14 using Server component and Server action

In this article, we will learn how to add documents to Firestore from Next.js 14 using Server component and Server action.

Video Tutorial

I have created a video tutorial which is a part of my Next.js 14 Firestore series on YouTube. You can watch the video tutorial for a better understanding of the topic.

Starter Code

You can use this repo to follow along. Use the starter branch to get the starter code. Also I assume you have a Firestore project setup and you have the credentials to access the Firestore. You can checkout the setup video here.

1// Import the functions you need from the SDKs you need
2import { initializeApp } from 'firebase/app'
3import { getFirestore } from 'firebase/firestore'
4
5// Your web app's Firebase configuration
6const firebaseConfig = {
7 // Values should be replaced with your own
8 apiKey: 'AIzaSyDYdXmF_MfLANTvC4bYBewFq9qh3ZdxiQY',
9 authDomain: 'next-fire-yt.firebaseapp.com',
10 projectId: 'next-fire-yt',
11 storageBucket: 'next-fire-yt.appspot.com',
12 messagingSenderId: '1098443682898',
13 appId: '1:1098443682898:web:b83b4a1d160d3b17511b8b',
14}
15
16// Initialize Firebase
17const app = initializeApp(firebaseConfig) // Initializing the app
18
19const db = getFirestore(app) // Accessing the the database
20
21export { db }
22
23export default app

Creating a server action

Server Actions are asynchronous functions that are executed on the server. They can be used in Server and Client Components to handle form submissions and data mutations in Next.js applications.

You can create a server action inside your server component or you can create a separate file for the server action. I prefer to create a separate file.

1// utils/firebase.js
2'use server'
3
4import { db } from '@/config/firebase'
5import { addDoc, collection, doc, serverTimestamp } from 'firebase/firestore'
6import { cookies } from 'next/headers'
7import { redirect } from 'next/navigation'
8
9const addPost = async formData => {
10 const collectionRef = collection(db, 'posts') // Reference to the collection
11 const userId = cookies().get('userId').value // Get the userId from the cookie
12
13 const userRef = doc(db, 'users', userId)
14 // const userRef = doc(db, `users/${userId}`) // Another way to get the reference
15
16 const docRef = await addDoc(collectionRef, {
17 title: formData.get('title'),
18 content: formData.get('content'),
19 tags: formData
20 .get('tags')
21 .split(',')
22 .map(tag => tag.trim()),
23 user: userRef,
24 })
25
26 redirect(`/post/${docRef.id}`) // Redirect to the newly created post
27}
28
29export { addPost }

Explanation:

  1. 'use server' is used to tell the server that this file will contain server actions.
  2. We need to create a reference to the collection where we want to add the document using collection function.
  3. collection takes two arguments, the first one is the database reference and the second one is path to the collection.
  4. You can get cookie value using cookies().get('cookieName').value. I will get the user id. Though this is not recommended, you should use a better way to get the user id. And it is optional.
  5. I have created a reference to the user document using doc function. I want to store the user reference in the post document. So that we can have a relation between the user and the post.
  6. addDoc function is used to add a document to the collection. It takes two arguments, the first one is the collection reference and the second one is the data to be added.
  7. Server action when used with forms takes formData as an argument. You can get the form data using formData.get('inputName'). Make sure to use name attribute in the input fields.
  8. If data is added successfully, you get document reference. You can use docRef.id to get the id of the newly created document.
  9. I have used redirect function to redirect to the newly created post.

Using the server action in the server component

You can use the server action in the server component to handle form submissions.

1const AddPostForm = () => (
2 <>
3 <form action={addPost}>
4 {/* Some input components */}
5 <Button type='submit'>Submit</Button>
6 </form>
7 </>
8)
9
10export default AddPostForm

Explanation:

  1. You can use the server action in the form action attribute.
  2. When the form is submitted, the server action is executed on the server. And you should be redirected to the newly created post.

setDoc function

You can use setDoc function to add a document to the collection. It creates a new document with the specified data, if it doesn't exist. If the document exists, it overwrites the document with the new data. You can pass the merge option to merge the data.

1await setDoc(docRef, {...data})`
2await setDoc(docRef, {...data}, {merge: true}) // merge with existing data

Conclusion

That's it. You have learned how to add documents to Firestore from Next.js 14 using Server component and Server action. Let me know if you have any questions or suggestions. Also please consider subscribing to my channel to see more Next.js related content.

Shameless Plug

I have made an Xbox landing page clone with React and Styled components. I hope you will enjoy it. Please consider like this video and subscribe to my channel.

That's it for this blog. I have tried to explain things simply. If you get stuck, you can ask me questions.

Contacts

Blogs you might want to read:

Videos might you might want to watch:

Previous PostHow to upload images or files on Firebase Cloud Storage with Nextjs 14
Next PostHow to get documents from Firebase Firestore in Nextjs14