πŸ’» λ°±μ—”λ“œ/Firebase

[Firebase] onsnapshot, get 차이 / νŠΈμœ— μ‚­μ œ μ‹€μ‹œκ°„ λ°˜μ˜ν•˜κΈ°

rigood 2023. 1. 17. 19:28

1. 문제 상황

νŠΈμœ— μ‚­μ œ λ²„νŠΌ 클릭 μ‹œ νŒŒμ΄μ–΄λ² μ΄μŠ€ DBμ—μ„œλŠ” μ‚­μ œλ˜μ—ˆμœΌλ‚˜ 화면에 λ°”λ‘œ λ°˜μ˜λ˜μ§€ μ•ŠμŒ

μƒˆλ‘œκ³ μΉ¨ν•˜κ±°λ‚˜ λ‹€λ₯Έ νŽ˜μ΄μ§€μ— κ°”λ‹€κ°€ λ‹€μ‹œ 듀어와야 화면에 반영됨

 

 

2. λ‹€λ₯Έ ν™”λ©΄μ—μ„œ νŠΈμœ—μ„ μ‚­μ œν•  λ•ŒλŠ” λ°”λ‘œ 반영됨

Profile νŽ˜μ΄μ§€μ—μ„œ νŠΈμœ—μ„ μ‚­μ œν•  λ•ŒλŠ” 화면에 λ°”λ‘œ λ°˜μ˜λ˜μ§€ μ•Šμ•˜μ§€λ§Œ,

Home νŽ˜μ΄μ§€μ—μ„œλŠ” μ‚­μ œλœ 내역이 화면에 λ°”λ‘œ 반영됨

 

 

 

3. μ½”λ“œ 비ꡐ (Profile vs Home)

화면에 λ°”λ‘œ λ°˜μ˜λ˜μ§€ μ•Šμ•˜λ˜ Profile μ»΄ν¬λ„ŒνŠΈμ—μ„œλŠ” get ν•¨μˆ˜λ₯Ό μ‚¬μš©ν–ˆκ³ ,

화면에 즉각 λ°˜μ˜λ˜μ—ˆλ˜ Home μ»΄ν¬λ„ŒνŠΈμ—μ„œλŠ” onSnapshot ν•¨μˆ˜λ₯Ό μ‚¬μš©ν–ˆμŒ

Homeμ—μ„œλŠ” νŠΈμœ— μ‚­μ œ μ‹œ λ¦¬λ Œλ”λ§μ΄ 일어났고, Profileμ—μ„œλŠ” λ¦¬λ Œλ”λ§ λ˜μ§€ μ•ŠμŒ (console.log둜 확인)

// Profile.jsx (getν•¨μˆ˜ μ‚¬μš©, λ¦¬λ Œλ”λ§X)

const getMyTweets = async () => {
    await dbService
      .collection("tweets")
      .where("creatorId", "==", userObj.uid)
      .orderBy("createdAt", "desc")
      .get()
      .then((data) => {
        const tweetArray = data.docs.map((doc) => ({
          id: doc.id,
          ...doc.data(),
        }));
        setMyTweets(tweetArray);
      });
  };

useEffect(() => {
	getMyTweets();
}, []);
// Home.jsx (onSnapshotν•¨μˆ˜ μ‚¬μš©, λ¦¬λ Œλ”λ§O)

useEffect(() => {
    dbService
      .collection("tweets")
      .orderBy("createdAt", "desc")
      .onSnapshot((snapshot) => {
        const tweetArray = snapshot.docs.map((doc) => ({
          id: doc.id,
          ...doc.data(),
        }));
        setTweets(tweetArray);
      });
  }, []);

 

 

4. get() vs onSnapshot() 

  • Firestoreμ—μ„œ 데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 방법은 get(), onSnapshot() 두가지가 있음
  • get()은 데이터λ₯Ό λ”± 1번만 뢈러옴. μ‹€μ‹œκ°„ 반영 μ•ˆλ˜κ³ , λ³€κ²½λœ λ‚΄μš©μ„ ν™•μΈν•˜λ €λ©΄ get()을 λ‹€μ‹œ ν˜ΈμΆœν•΄μ•Όν•¨
  • onSnapshot()은 데이터 변경을 κ°μ§€ν•˜λŠ” λ¦¬μŠ€λ„ˆλ₯Ό λ‹¬μ•„μ£ΌλŠ” κ²ƒμž„. 데이터가 변경될 λ•Œλ§ˆλ‹€ μŠ€λƒ…μƒ·μ΄ μƒμ„±λ˜μ–΄, μ‹€μ‹œκ°„μœΌλ‘œ 변경내역을 확인할 수 있음
  • 데이터λ₯Ό 뿌렀주기만 ν•  λ•ŒλŠ” get(), CRUDλ₯Ό μ‹€μ‹œκ°„μœΌλ‘œ λ°˜μ˜ν•΄μ•Ό ν•  λ•ŒλŠ” onSnapshot() μ‚¬μš©

 

There are two ways to retrieve data stored in Cloud Firestore. Either of these methods can be used with documents, collections of documents, or the results of queries:
- Call a method to get the data.
- Set a listener to receive data-change events.

 

When you set a listener, Cloud Firestore sends your listener an initial snapshot of the data, and then another snapshot each time the document changes.

 

When you use get() you "retrieve the content of a single document" only once. It's a kind of "get and forget": If the document changes in the (back-end) Firestore database you will need to call get() again to see the change.

On the opposite, if you use the onSnapshot() method you constantly listen to a document as explained in the doc:

 

You can listen to a document with the onSnapshot() method. An initial call using the callback you provide creates a document snapshot immediately with the current contents of the single document. Then, each time the contents change, another call updates the document snapshot.

 

As explained in these docs, these two methods apply to one document or to a collection of documents (including a query).

 

좜처: https://stackoverflow.com/questions/54479892/difference-between-get-and-onsnapshot-in-cloud-firestore

 

 

5. μ½”λ“œ μˆ˜μ • get()->onSnapshot()

onSnapshot으둜 λ°”κΎΈλ‹ˆ Profile νŽ˜μ΄μ§€μ—μ„œλ„ νŠΈμœ— μ‚­μ œ μ‹œ λͺ©λ‘μ— λ°”λ‘œ 반영됨

// Profile.jsx

useEffect(() => {
    dbService
      .collection("tweets")
      .where("creatorId", "==", userObj.uid)
      .orderBy("createdAt", "desc")
      .onSnapshot((snapshot) => {
        const tweetArray = snapshot.docs.map((doc) => ({
          id: doc.id,
          ...doc.data(),
        }));
        setMyTweets(tweetArray);
      });
  }, []);