|
6 | 6 | onSnapshot, |
7 | 7 | query, |
8 | 8 | where, |
9 | | - orderBy, |
10 | 9 | Timestamp, |
11 | 10 | } from "firebase/firestore"; |
12 | 11 | import { db } from "@/lib/firebase"; |
@@ -36,34 +35,40 @@ export default function PopularArticles({ |
36 | 35 | useState<Article[]>(initialArticles); |
37 | 36 |
|
38 | 37 | useEffect(() => { |
39 | | - // Query Firestore for articles that have popularity == true AND publish == true |
40 | | - // Then order by date descending (assuming 'date' is a valid field in the documents) |
| 38 | + // Keep the live query on one indexed field, then filter and rank locally. |
| 39 | + // This avoids requiring a composite index for the public sidebar. |
41 | 40 | const articlesQuery = query( |
42 | 41 | collection(db, "articles"), |
43 | | - where("popularity", "==", true), |
44 | 42 | where("publish", "==", true), |
45 | | - orderBy("popularityRank", "asc"), |
46 | 43 | ); |
47 | 44 |
|
48 | 45 | const unsubscribe = onSnapshot( |
49 | 46 | articlesQuery, |
50 | 47 | (snapshot) => { |
51 | | - const articles: Article[] = snapshot.docs.map((doc) => { |
52 | | - const data = doc.data(); |
53 | | - return { |
54 | | - id: doc.id, |
55 | | - title: data.title || "", |
56 | | - slug: data.slug || "", |
57 | | - authorName: data.authorName || "Unknown Team Member", |
58 | | - popularity: data.popularity || false, |
59 | | - publish: data.publish || false, |
60 | | - date: |
61 | | - data.date instanceof Timestamp |
62 | | - ? data.date |
63 | | - : (data.date ?? new Date().toISOString()), |
64 | | - popularityRank: data.popularityRank, |
65 | | - } as Article; |
66 | | - }); |
| 48 | + const articles: Article[] = snapshot.docs |
| 49 | + .map((doc) => { |
| 50 | + const data = doc.data(); |
| 51 | + return { |
| 52 | + id: doc.id, |
| 53 | + title: data.title || "", |
| 54 | + slug: data.slug || "", |
| 55 | + authorName: data.authorName || "Unknown Team Member", |
| 56 | + popularity: data.popularity || false, |
| 57 | + publish: data.publish || false, |
| 58 | + date: |
| 59 | + data.date instanceof Timestamp |
| 60 | + ? data.date |
| 61 | + : (data.date ?? new Date().toISOString()), |
| 62 | + popularityRank: data.popularityRank, |
| 63 | + } as Article; |
| 64 | + }) |
| 65 | + .filter((article) => article.popularity) |
| 66 | + .sort( |
| 67 | + (left, right) => |
| 68 | + (left.popularityRank ?? Number.MAX_SAFE_INTEGER) - |
| 69 | + (right.popularityRank ?? Number.MAX_SAFE_INTEGER) || |
| 70 | + left.title.localeCompare(right.title), |
| 71 | + ); |
67 | 72 |
|
68 | 73 | setPopularArticles(articles); |
69 | 74 | }, |
|
0 commit comments