I’m trying to add posts to my Firestore database, but I’m running into an issue where the userId field (which should contain the logged-in user’s ID) isn’t being saved in the document. Here’s
I’m attempting to add a new post to Firestore in my React Native app. Each post should include fields like userId (from the logged-in user), content, timestamp, etc. I have checked the following:
The user is authenticated, and user.uid appears as expected when I log it to the console.
My Firestore security rules allow authenticated users to write to the posts collection.
I’m calling addDoc
on the posts collection, but no new documents are appearing in Firestore.
I expected the post to save successfully, with userId
populated from the logged-in user’s uid. User id is undefined or doesn’t exist. However, the document is not being saved at all, and no errors are being thrown in my code.
cannot find userid Something went wrong with adding post to Firestore:’, error).
path: apppostsposts.jsx
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
Image,
ScrollView,
Alert
} from 'react-native';
import React, { useContext, useState } from 'react';
import { AntDesign, Feather } from '@expo/vector-icons';
import { useRouter } from 'expo-router';
import { useAuth } from '../context/authContext';
import * as ImagePicker from 'expo-image-picker';
import { getFirestore, collection, addDoc } from 'firebase/firestore';
import { getStorage, ref, uploadBytes, getDownloadURL } from 'firebase/storage';
const AddPost = () => {
const router = useRouter();
const { user } = useContext(useAuth);
const handleClose = () => {
router.back();
};
const [image, setImage] = useState(null);
const [post, setPost] = useState('');
const handlePost = async () => {
if (!user) {
Alert.alert('Error', 'You must be logged in to post.');
return;
}
const imageUrl = await uploadImage();
console.log('Image Url:', imageUrl);
console.log('Post:', post);
const db = getFirestore();
try {
await addDoc(collection(db, 'posts'), {
userId: user.uid, // Ensure user.uid is defined
post: post,
postImg: imageUrl,
postTime: new Date(),
likes: [],
comments: [],
});
console.log('Post Added');
Alert.alert('Post published', 'Your Post has been published');
setPost('');
setImage(null);
} catch (error) {
console.log('Something went wrong with adding post to Firestore:', error);
Alert.alert('Error', 'Something went wrong while adding your post.');
}
};
const uploadImage = async () => {
if (!image) {
return null; // Return null if there's no image
}
const response = await fetch(image);
const blob = await response.blob();
const storage = getStorage();
const storageRef = ref(storage, `photos/${Date.now()}`);
try {
await uploadBytes(storageRef, blob);
const url = await getDownloadURL(storageRef);
return url;
} catch (e) {
console.log('Image upload error:', e);
return null;
}
};
const handleAddMedia = async () => {
const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (permissionResult.granted === false) {
Alert.alert('Permission required', 'Permission to access camera roll is required!');
return;
}
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (!result.cancelled) {
setImage(result.uri);
}
};
return (
<ScrollView style={styles.container}>
<View style={styles.header}>
<TouchableOpacity onPress={handleClose}>
<AntDesign name="arrowleft" size={24} color="black" />
</TouchableOpacity>
<Text style={styles.headerTitle}>Add Post</Text>
<TouchableOpacity onPress={handlePost}>
<Text style={styles.postButton}>Post</Text>
</TouchableOpacity>
</View>
<View style={styles.content}>
<TextInput
style={styles.textInput}
placeholder="What's on your mind?"
multiline
numberOfLines={4}
value={post}
onChangeText={setPost}
/>
<TouchableOpacity onPress={handleAddMedia} style={styles.addMediaButton}>
<Feather name="image" size={20} color="white" />
<Text style={styles.addMediaText}>Add Media</Text>
</TouchableOpacity>
{image && (
<>
<Image source={{ uri: image }} style={styles.imagePreview} />
<Text style={styles.imagePreviewText}>{image}</Text>
</>
)}
</View>
</ScrollView>
);
};
export default AddPost;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingHorizontal: 16,
paddingTop: 25,
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 20,
},
headerTitle: {
fontSize: 18,
fontWeight: 'bold',
textTransform: 'capitalize',
},
postButton: {
color: '#34c759',
fontWeight: 'bold',
textTransform: 'uppercase',
},
content: {
marginVertical: 20,
},
textInput: {
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 10,
padding: 16,
height: 120,
fontSize: 16,
marginBottom: 10,
},
addMediaButton: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#34c759',
padding: 10,
borderRadius: 10,
justifyContent: 'center',
},
addMediaText: {
color: '#fff',
fontWeight: 'bold',
marginLeft: 5,
},
imagePreview: {
width: '100%',
height: 200,
marginTop: 10,
borderRadius: 10,
resizeMode: 'cover',
},
imagePreviewText: {
color: '#888',
fontSize: 12,
marginTop: 5,
textAlign: 'center',
},
});
path: appcontextauthContext.jsx
import { createContext, useContext, useEffect, useState } from "react";
import {
onAuthStateChanged,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut
} from "firebase/auth";
import { auth, databaseFB } from "../../FirebaseConfig";
import { doc, getDoc, setDoc } from "firebase/firestore";
// Create the context
export const AuthContext = createContext();
// AuthContextProvider component
export const AuthContextProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [isAuthenticated, setIsAuthenticated] = useState(undefined);
// Monitor authentication state
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
if (user) {
setIsAuthenticated(true);
updateUserData(user.uid);
} else {
setIsAuthenticated(false);
setUser(null);
}
});
return unsub;
}, []);
const updateUserData = async (userId) => {
const docRef = doc(databaseFB, 'users', userId);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
const data = docSnap.data();
setUser({ ...user, username: data.username, userType: data.userType, userId: data.userId });
} else {
console.log('No such document in users collection!');
}
};
// Login function
const login = async (email, password) => {
try {
const response = await signInWithEmailAndPassword(auth, email, password);
setUser(response.user);
setIsAuthenticated(true);
return { success: true, data: response.user };
} catch (e) {
let msg = e.message;
if (msg.includes('auth/wrong-password')) msg = 'Wrong password';
if (msg.includes('auth/invalid-email')) msg = 'Invalid email';
if (msg.includes('auth/user-not-found')) msg = 'User not found';
return { success: false, msg };
}
};
// Logout function
const logout = async () => {
try {
await signOut(auth);
setUser(null);
setIsAuthenticated(false);
return { success: true };
} catch (e) {
return { success: false, msg: e.message, error: e };
}
};
// Register function
const register = async (email, password, username, userType) => {
try {
if (!username || !userType) {
return { success: false, msg: 'Username and user type are required' };
}
const response = await createUserWithEmailAndPassword(auth, email, password);
await setDoc(doc(databaseFB, "users", response.user.uid), {
username,
userType,
userId: response.user.uid,
});
return { success: true, data: response.user };
} catch (e) {
let msg = e.message;
if (msg.includes('auth/invalid-email')) msg = 'Invalid email';
return { success: false, msg };
}
};
return (
<AuthContext.Provider value={{ user, isAuthenticated, login, register, logout }}>
{children}
</AuthContext.Provider>
);
};
// Custom hook for consuming auth context
export const useAuth = () => {
const value = useContext(AuthContext);
if (!value) {
throw new Error("useAuth must be wrapped inside AuthContextProvider");
}
return value;
};
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth, initializeAuth, getReactNativePersistence } from 'firebase/auth';
import { getFirestore, collection } from 'firebase/firestore';
import AsyncStorage from '@react-native-async-storage/async-storage';
// Firebase configuration
const firebaseConfig = {
apiKey: "AIzaSyAe3TwmcwhAoSqtNT12XBsHFqFkUxnSx0g",
authDomain: "internconnectdb.firebaseapp.com",
projectId: "internconnectdb",
storageBucket: "internconnectdb.appspot.com",
messagingSenderId: "445282960631",
appId: "1:445282960631:web:a2cf595a4f345f62933ff2"
};
FirebaseConfig.ts
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const auth = initializeAuth(app,{
persistence: getReactNativePersistence(AsyncStorage)
});
export const databaseFB = getFirestore(app);
export const usersRef = collection(databaseFB,'users');