I am trying to show a tab bar badge for my notifications tab. If a user has a notification, after writing the notification in the backend, I set a field for the user "hasNotifications" as true. Once I click on the notifications tab, I set "hasNotifications" to false.
Here is my implementation:
function renderBadge() {
Firebase.firestore()
.collection('users')
.doc(Firebase.auth().currentUser.uid)
.onSnapshot(function(doc) {
if (doc.data().hasNotifications) {
console.log("true")
return true
}
else {
console.log("null")
return null
}
})
}
//Bottom Tabs
function Tabs() {
return (
<Tab.Navigator
initialRouteName="Home"
tabBarOptions={{
activeTintColor:"#FFFFFF",
inactiveTintColor:"#696969",
style: {
backgroundColor: '#000000',
borderTopColor: "transparent"
},
}}>
<Tab.Screen
name="Notificaton"
component={Notification}
options={{
tabBarLabel: ' ',
tabBarIcon: ({ color, size }) => (
<Ionicons name="md-notifications" size={size} color={color} />
),
tabBarBadge: renderBadge() <----- Render red dot if true, no red dot if null
}}
/>
</Tab.Navigator>
);
}
The console logging shows me the listener is working, and returns true/null based on whether the user has notifications. But the tab bar badge does NOT show up. How can I fix this?
EDIT: Looks like when I set tabBarBadge: renderBadge()
, the badge never shows up. When I set tabBarBadge: renderBadge
, the badge always shows up. The listener is working fine, but this is not.
EDIT 2: I changed the function to const renderBadge = () => {
, and it still doesn't work.
I know react (for browsers) better than react-native, but if the paradigm is the same, you should change the following aspects:
useState
to hold the boolean value; change the value provided by its setter function
useEffect
, perhaps with Firebase.auth().currentUser.uid
as a dependency.
Firebase...onSnapshot(...)
from within the useEffect
callback in order to properly destroy the firebase-subscription if the component is not needed anymore - see https://firebase.google.com/docs/reference/node/firebase.firestore.CollectionReference#returns-=-voidThe result could be similar to this:
function useNotificationsBadge() {
const [hasNotifications, setHasNotifications] = useState(null);
const userId = Firebase.auth().currentUser.uid;
useEffect(
() => Firebase.firestore()
.collection('users')
.doc(userId)
.onSnapshot(function(doc) {
const newHasNotifications = doc.data().hasNotifications ? true : null;
setHasNotifications(newHasNotifications);
}),
[userId]
);
return hasNotifications;
}
In your component you can then write;
...
const hasNotifications = useNotificationsBadge();
...
tabBarBadge: hasNotifications
My personal recommendation would be to replace null
by false
in this snippet to make the API more clear.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.