Reputation: 319
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.
Upvotes: 2
Views: 2634
Reputation: 3292
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.
Upvotes: 2