#javascript #firebase #google-cloud-firestore
#javascript #firebase #google-облако-firestore
Вопрос:
я создал систему вывода средств. у меня ошибка. пример: пользователь имеет 100 баллов. минимальная сумма для вывода равна 5. теперь, если он больше, чем у него есть, его сумма добавляется к сумме (-) (снимаю 200, а у меня только 100, моя сумма становится -100)
я пишу этот код, чтобы предотвратить его, но это не работает. любая помощь, пожалуйста, крайний срок — сегодня, и у меня было несколько ошибок 🙂
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.5.0/firebase-app.js";
import {
getFirestore,
collection,
onSnapshot,
addDoc,
deleteDoc,
getDoc,
setDoc,
doc,
query,
where,
orderBy,
serverTimestamp,
updateDoc,
arrayUnion,
arrayRemove,
} from "https://www.gstatic.com/firebasejs/9.5.0/firebase-firestore.js";
import {
getAuth,
signOut,
} from "https://www.gstatic.com/firebasejs/9.5.0/firebase-auth.js";
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "Ow",
authDomain: ".firebaseapp.com",
projectId: "egyfaucet",
storageBucket: ".appspot.com",
messagingSenderId: "",
appId: "1::web:"
};
// init firebase
initializeApp(firebaseConfig);
// const FieldValue = require('firebase-admin').firestore.FieldValue;
// init services
const db = getFirestore();
const auth = getAuth();
// const batch = db.batch();
// collection ref
const colRef = collection(db, "payments");
const colRefBound = collection(db, "bound");
const colRefUsers = collection(db, "users");
// Queires
const q = query(colRef, orderBy("createdAt"));
const requestBtn = document.querySelector("#added .big-input button");
const requestInput = document.querySelector("#added .big-input input");
// Validation
requestBtn.addEventListener("click", async function (){
if(ValidationWallet(requestInput.value)){
const { value: Amount } = await Swal.fire({
icon:'question',
title:'Amount',
inputLabel: 'Select The Withdrawl Amount',
showCancelButton: true,
showCloseButton: true,
cancelButtonColor: '#dc3545',
confirmButtonText: 'Confirm',
confirmButtonColor: '#0088FF',
cancelButtonAriaLabel: 'Thumbs down',
input:'text',
preConfirm: () => this.Amount
});
if(ValidationAmount(Amount)){
Swal.fire("Success","The Draw Is Waiting For Review","success");
sendWithdrawlRequest(Amount) // This Function Bottom (DB)
}else{
Swal.fire("Ops!","Please Put The Valid Amount","error");
}
}else{
Swal.fire("Ops!","Please Check Your Wallet","error");
}
});
// Validation Function
function ValidationWallet(val) {
if(
val !== ""
amp;amp; val.length >= 10
amp;amp; true /* => Here Put Check In Wallet Adress API (DB) */
){
return true
}else{
return false;
}
}
function ValidationAmount(val) {
auth.onAuthStateChanged((user) => {
const userRef = doc(db, "users", user.uid);
onSnapshot(userRef, (doc) => {
console.log(doc.data().earningsCount);
if (val >= doc.data().earningsCount) {
return false;
}
})
})
if (val < 5) {
return false;
}
if(val !== ""
amp;amp; val > 0
amp;amp; isNaN(val) == false
amp;amp; true /* => Here Put Check In Her Pont In (DB) >= amount*/
) {
return true
} else{
return false;
}
}
// DB
function sendWithdrawlRequest(Amount){
Amount = Amount;
auth.onAuthStateChanged((user) => {
const paymentRef = doc(db, "payments", user.uid);
const userRef = doc(db, "users", user.uid);
let today = new Date();
let date = today.getFullYear() '-' (today.getMonth() 1) '-' today.getDate();
const requestCode = Math.random().toString(36).substr(2, 9);
setDoc(doc(db, "payments", requestCode),{
amount: Amount,
walletID: requestInput.value,
requestID: requestCode,
createdAt: date,
});
// add a pauments to the "user.payments" array field and (-) the amount in input.
getDoc(userRef).then((doc) => {
updateDoc(userRef, {
earningsCount:
doc.data().earningsCount - Amount,
payments: arrayUnion({ amount: Amount, walletID: requestInput.value, createdAt: date,}),
});
});
});
// console.log(requestInput.value);
// console.log(Amount); //Here Put Block Of Code To Senf Request
};
// push payment for user
const paymentsList = document.querySelector("#paymentsList");
// Real Time Collection data
onSnapshot(q, (snapshot) => {
let payments = [];
snapshot.docs.forEach((doc, i) => {
payments.push({ ...doc.data() });
});
auth.onAuthStateChanged((user) => {
if (user) {
const userRef = doc(db, "users", user.uid);
getDoc(userRef).then((doc) => {
// console.log(doc.data().payments[0].amount);
const pendingPayments = doc.data().payments;
let html = "";
pendingPayments.forEach((payment, i) => {
// console.log(payment.count);
// console.log(link);
const div = `
<tr>
<td>${payment.amount}
lt;/td>
<td>${payment.createdAt}</td>
</tr>
`
;
html = div;
});
// Display payments from DB into Users UI
paymentsList.innerHTML = html;
});
}
});
});
Ответ №1:
Если вы хотите, чтобы значение не earningsCount
стало отрицательным, вы можете сделать это в правилах безопасности для вашей базы данных:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{uid} {
allow write: if
// Users can only write their own document
request.auth != null amp;amp; request.auth.uid == request.resource.data.author_uid
// And their earningsCount can never become negative
request.resource.data.earningsCount >= 0
}
}
}
Эти правила автоматически выполняются на сервере при каждом обращении к данным, поэтому код вашего приложения (или любой код, который злоумышленник может запустить с вашими данными конфигурации) не может обойти эти правила.
Я настоятельно рекомендую прочитать документацию Firestore по защите вашей базы данных, чтобы узнать больше об этом.