I want to add the total number of clicks using the increment field value but when I try to open the link I created, the total clicks do not increase at all.
did I do something wrong?
import {useParams} from 'react-router-dom';
import { useEffect, useState } from 'react';
import React from 'react';
import { firestore, app } from '../../firebase';
import { CircularProgress, Box, Typography } from '@mui/material';
function LinkRedirect() {
const {shortCode} = useParams();
const [loading, setLoading] = useState(true)
useEffect(() => {
const fethLinkDoc = async () => {
const linkDoc = await firestore.collection('links').doc(shortCode).get();
if (linkDoc.exists){
const{ longURL, linkID, userUid} = linkDoc.data();
firestore.collection('users').doc(userUid).collection('links').doc(linkID).update({
totalClicks: app.firestore.FieldValue.increment(1)
})
window.location.href = longURL;
} else {
setLoading(false)
}
}
fethLinkDoc()
}, [])
if (loading)
return (
<Box mt={10} textAlign="center">
<CircularProgress />
<Typography>Redirecting to the link</Typography>
</Box>
)
else return (
<Box mt={10} textAlign="center">
<Typography>Link is not valid</Typography>
</Box>
)
}
export default LinkRedirect
CodePudding user response:
The problem is caused by these lines:
firestore.collection('users').doc(userUid).collection('links').doc(linkID).update({
totalClicks: app.firestore.FieldValue.increment(1)
})
window.location.href = longURL;
Here you queue the document update operation to increment the counter, then immediately navigate away from the page, cancelling the operation.
Because you are using an async
function, you can simply add await
before the call to update()
:
await firestore.collection('users').doc(userUid).collection('links').doc(linkID).update({
totalClicks: app.firestore.FieldValue.increment(1)
})
window.location.href = longURL;
However, I'd refactor your fethLinkDoc
method to the following for readability:
const fethLinkDoc = async () => {
const linkDoc = await firestore.collection('links').doc(shortCode).get();
if (!linkDoc.exists) { // fail-fast
setLoading(false)
return
}
const { longURL, linkID, userUid } = linkDoc.data();
await firestore.collection('users')
.doc(userUid)
.collection('links')
.doc(linkID)
.update({
totalClicks: app.firestore.FieldValue.increment(1)
})
window.location.href = longURL;
}
Note: Your code currently doesn't properly handle when any of the firebase operations reject their promises. Either handle it manually or make use of an utility method like useAsyncEffect
from a library.