英文:
How to add a live counter in react that displays a firestore collection value securely?
问题
目标: 在我的React Firebase网站上有一个实时计数器,显示我的YouTube频道的当前观看次数。
方法: 我通过调用YouTube API从Firebase云函数中检索观看次数,以保护我的API密钥。一旦我获取了数据,我使用另一个云函数来更新我的Firestore数据库中的观看次数集合(使用pubsub每60分钟)。然后,我在前端使用onSnapshot来监视这个集合并显示该值。
问题: 尽管这确实有效,但我每天都会收到来自Firebase的电子邮件,说我的Firestore数据库“存在不安全的规则”,因为“任何用户都可以读取整个数据库”。我不想为我的网站添加身份验证,但我希望实时计数器是完全安全的。有人知道如何实现引用Firestore数据库的实时计数器吗?
前端代码:
export default function Navbar() {
const [count, setCount] = React.useState('');
const unsub = onSnapshot(doc(db, "viewCount", "Count"), (doc) => {
setCount(doc.get("View Count"));
});
}
Firestore规则:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if true;
allow write: if false;
}
}
}
云函数:
/**
* 每60分钟更新Firestore的观看次数的函数
*
* @param -
* @returns - 无
*/
exports.updateViewCount = functions.pubsub
.schedule("every 60 minutes")
.onRun((context) => {
try {
this.logCount(5);
console.log("Count updated at:", new Date());
} catch (error) {
console.error("Error getting view count: ", error);
}
});
/**
* 函数调用getViewCount获取YouTube观看次数
*
* @param -
* @returns - Int: 观看次数
*/
exports.logCount = functions
.runWith({
secrets: ["YOUTUBE_API"],
})
.https.onCall(async (data, context) => {
const viewData = await getViewCount(
process.env.YOUTUBE_API,
process.env.YOUTUBE_CHANNEL_ID
);
const addData = await admin
.firestore()
.collection("viewCount")
.doc("Count")
.set({ "View Count": viewData })
.then(() => {
return viewData;
})
.catch((error) => {
console.error("Error writing document: ", error);
});
});
总结:
- 这是否是在Firestore中实现不需要身份验证的实时计数器的正确方式?
- 如果是的话,如何更安全地实现这一点?如果不是,还有哪些其他选项?
英文:
Goal: To have a live counter on my React Firebase site that displays the current number of views on my youtube channel.
Method: I am retrieving the view count by calling the Youtube API from a firebase cloud function so that I can protect my API key. Once I have the data, I use another cloud function to update a view count collection in my firestore database (using pubsub every 60 minutes). I then monitor this collection using onSnapshot in my front-end and display the value.
Problem: While this does work, I get an email every day from Firebase saying my firestore database "has insecure rules" because "any user can read the entire database." I do not want to add authentication to my site, but I would like to have the live counter fully secure. Does anybody know how to have a live counter referencing a firestore database?
Front-end code:
export default function Navbar() {
const [count, setCount] = React.useState('');
const unsub = onSnapshot(doc(db, "viewCount", "Count"), (doc) => {
setCount(doc.get("View Count"));
});
Firestore rules:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if true;
allow write: if false;
}
}
}
Cloud functions
/**
* Function updates Firestore view count every 60 minutes
*
* @param -
* @returns - N/A
*/
exports.updateViewCount = functions.pubsub
.schedule("every 60 minutes")
.onRun((context) => {
try {
this.logCount(5);
console.log("Count updated at:", new Date());
} catch (error) {
console.error("Error getting view count: ", error);
}
});
/**
* Function calls getViewCount to get Youtube View Count
*
* @param -
* @returns - Int: View count
*/
exports.logCount = functions
.runWith({
secrets: ["YOUTUBE_API"],
})
.https.onCall(async (data, context) => {
const viewData = await getViewCount(
process.env.YOUTUBE_API,
process.env.YOUTUBE_CHANNEL_ID
);
const addData = await admin
.firestore()
.collection("viewCount")
.doc("Count")
.set({ "View Count": viewData })
.then(() => {
return viewData;
})
.catch((error) => {
console.error("Error writing document: ", error);
});
});
To recap:
- Is this the right way to implement a live counter with firestore without authentication?
- If so: How can I do this more securely? If not: what other options are there?
答案1
得分: 2
要停止警告邮件,您只需要更改您的规则,以便不将 allow read: if true;
应用于整个数据库。您仍然可以将其应用于包含计数器的数据库部分。
service cloud.firestore {
match /databases/{database}/documents {
match /viewCount/Count {
allow read: if true;
allow write: if false;
}
}
}
如果您的应用还使用其他文档和集合,您需要为它们添加规则。
英文:
To get the warning emails to stop, you just need to change your rules so that allow read: if true;
isn't applied to the entire database. You can still apply it to the part of the database where the counter is.
service cloud.firestore {
match /databases/{database}/documents {
match /viewCount/Count {
allow read: if true;
allow write: if false;
}
}
}
If you have other documents and collections that are being used by your app, you'll need to add rules for them too.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论