try {
const res = await getDoc(doc(db, "chats", combinedId));
if (!res.exists()) {
//create a chat in chats collection
await setDoc(doc(db, "chats", combinedId), { messages: [] });
//create user chats
await updateDoc(doc(db, "userChats", currentUser.uid), {
[combinedId + ".userInfo"]: {
uid: user.uid,
displayName: user.displayName,
photoURL: user.photoURL,
},
[combinedId + ".date"]: serverTimestamp(),
});
await updateDoc(doc(db, "userChats", user.uid), {
[combinedId + ".userInfo"]: {
uid: currentUser.uid,
displayName: currentUser.displayName,
photoURL: currentUser.photoURL,
},
[combinedId + ".date"]: serverTimestamp(),
});
}
} }
I tried to make collections userChats and chats for compound queries but nothing apear except users from registration
I have tried change the rule ,but still no collections sit in firebase except user, my rule in firebase is
enter image description here
firebase collections is enter image description here
Related
I keep getting the error above when trying to sign in with Google on Firebase. My code
const provider = new GoogleAuthProvider();
export const auth = getAuth();
export async function signUpGoogle(userType) {
return await signInWithPopup(auth, provider)
.then((result) => {
// This gives you a Google Access Token. You can use it to access the Google API.
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential.accessToken;
// The signed-in user info.
const user = result.user;
// ...
// create user in firestore
//init services
// Add a new document in collection "users"
setDoc(collection(db, "users", "/", `${userType}`, '/', 'users'), {
userId: user.uid,
firstName: user.displayName,
lastName: user.displayName,
contactNumber: user.phoneNumber,
county: "",
idNumber: "",
city: "",
zipCode: "",
fullName: "",
email: user.email,
imageAsUrl: {
imageAsUrl: user.photoURL,
},
}).catch((e) => {
console.log(e.toString());
});
sessionStorage.setItem("Auth Token", token);
return true
}).catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
// The email of the user's account used.
const email = error.email;
// The AuthCredential type that was used.
const credential = GoogleAuthProvider.credentialFromError(error);
console.log(errorCode, errorMessage);
console.log(error);
// ...
return false
});
}
I have folowed the google documentation about signin with google and javascript
The error that i am getting is
FirebaseError: Expected type 'Zu', but it was: a custom ea object
The setDoc() takes a DocumentReference as a parameter i.e. you must specify the document ID. You can use addDoc() instead if you want to generate a random ID. But it might be useful to use user's UID as the document ID itself so try:
setDoc(doc(db, `users/${userType}/users/${user.uid}`), {
userId: user.uid,
firstName: user.displayName,
// ...
}).catch((e) => {
console.log(e.toString());
});
This code creates a new document every time the user logs in but my task is to update existing same user ID document if it exists else create a new one. How can I do that in V9 Firebase?
Current Code
setDoc(
query(collectionRef),
// db.collection('users').doc(user.uid).set(
{
email: user.email,
lastSeen: serverTimestamp(),
photoURL: user.photoURL
}, {
merge: true
}
);
Old Code that access document UID:
The first parameter in setDoc() should be DocumentReference:
import { doc, setDoc } from "firebase/firestore"
const docRef = doc(db, "users", user.uid);
setDoc(docRef, {
email: user.email,
lastSeen: serverTimestamp(),
photoURL: user.photoURL
}, {
merge: true
}).then(() => console.log("Document updated"));
Alternatively, You can also use updateDoc().
import {
doc,
updateDoc
} from "firebase/firestore"
update(doc(db, "users", user.uid, {
email: user.email,
lastSeen: serverTimestamp(),
photoURL: user.photoURL
}).then(() => console.log("Document updated"));
db.collection("rooms").doc(channelId).collection("messages").add({
message: input,
timestamp: serverTimestamp(),
user: 'Apollos',
userImage: 'https://naniwallpaper.com/files/wallpapers/eren-yeager/1-EREN%20YEAGER-1080x1920.jpg'
});
How should this be in firestore v9?
import { doc } from "firebase/firestore";
const messageRef = doc(db, "rooms", chanelID, "messages");
const update = {
message: input,
timestamp: serverTimestamp(),
user: 'Apollos',
userImage: 'https://naniwallpaper.com/files/wallpapers/eren-yeager/1-EREN%20YEAGER-1080x1920.jpg'
}
setDoc(messageRef, update, { merge: true });
I have two ways to register a user in Firebase: through email and through Google Sign In.
I perform the user registration by email as follows:
signUp() {
const auth = getAuth();
const db = getFirestore();
createUserWithEmailAndPassword(
auth,
this.createEmail,
this.createPassword
).then(
(userCredential) => {
const user = userCredential.user;
this.$router.push("/");
addDoc(collection(db, "users"), {
email: this.createEmail,
name: this.createName,
});
},
);
},
In other words, in addition to saving the user in Firebase Authentication, I also send their name and email to Firestore. And this is my first question:
Is it the most effective way to save the username and future data that will still be added to it?
Finally, login by Google is done as follows:
googleSignIn() {
const auth = getAuth();
const provider = new GoogleAuthProvider();
signInWithPopup(auth, provider)
.then((result) => {
this.$router.push("/");
addDoc(collection(db, "users"), {
email: result.user.email,
name: result.user.displayName,
});
})
},
Here a problem arises because if a user logs in more than once in Firebase Authentication everything is ok, but in Firebase Firestore a user is created for each new login with Google.
How do I handle this issue of storing users in Firestore, especially users coming from Google Login?
First, I'd move the router.push() statement below addDoc() so I can confirm that the document has been added and then user is redirected to other pages. In case of Google SignIn, you can check if the user is new by accessing the isNewUser property by fetching additional information. If true, then add document to Firestore else redirect to dashboard:
signInWithPopup(auth, provider)
.then(async (result) => {
// Check if user is new
const {isNewUser} = getAdditionalUserInfo(result)
if (isNewUser) {
await addDoc(collection(db, "users"), {
email: result.user.email,
name: result.user.displayName,
});
}
this.$router.push("/");
})
It might be a good idea to set the document ID as user's Firebase Auth UID instead of using addDoc() which generated another random ID so it's easier to write security rules. Try refactoring the code to this:
signInWithPopup(auth, provider)
.then(async (result) => {
// Check if user is new
const {isNewUser} = getAdditionalUserInfo(result)
const userId = result.user.uid
if (isNewUser) {
await setDoc(doc(db, "users", userId), {
email: result.user.email,
name: result.user.displayName,
});
}
this.$router.push("/");
})
I'm working on a signup form. User registers, then in Firebase in the "companies" collection I add a new company, then a "users" collection is added under the just-created company, and the just-created user is added as a document to the company.
Everything is working fine until my code tries to add a new collection "users" under the just created company. Here's my code thus far:
return async (dispatch, getState) => {
try {
const { companyName, email, password } = getState().user;
const response = await Firebase.auth().createUserWithEmailAndPassword(
email,
password
);
if (response.user.uid) {
// Set up company
const company = {
name: companyName,
owner: response.user.uid
};
// Create company
db.collection("companies")
.add(company)
.then(ref => {
console.log("Company ID ", ref.id);
console.log("User ID ", response.user.uid);
// Set up first user
const user = {
uid: response.user.uid,
email: email
};
// Add first User
db.doc(ref.id)
.collection("users")
.add(user);
});
dispatch({ type: SIGNUP, payload: user });
}
} catch (e) {
alert(e);
}
};
Those console.logs return the correct IDs, So it looks like there's an issue with how my reference to the just-created company is being created? How would I fix that?
db.doc(ref.id).collection("users").add(user) may be wrong.
Could you try ref.collection("users").add(user) or db.collection("companies").doc(ref.id).collection("users").add(user);
// Add first User
// db.doc(ref.id)
// .collection("users")
// .add(user);
ref.collection("users").add(user);
// db.collection("companies").doc(ref.id).collection("users").add(user);
See:
https://firebase.google.com/docs/reference/js/firebase.firestore.CollectionReference#add
https://firebase.google.com/docs/reference/js/firebase.firestore.DocumentReference#collection
https://firebase.google.com/docs/reference/js/firebase.firestore.Firestore#doc
In addition to zkohi's correct answer, note that you are mixing the use of async/await with then(), which is not recommended. The following should do the trick (untested):
return async (dispatch, getState) => {
try {
const { companyName, email, password } = getState().user;
const response = await Firebase.auth().createUserWithEmailAndPassword(
email,
password
);
if (response.user.uid) {
// Set up company
const company = {
name: companyName,
owner: response.user.uid,
};
// Create company
const compRef = await db.collection('companies').add(company);
console.log('Company ID ', compRef.id);
const user = {
uid: response.user.uid,
email: email,
};
await compRef.collection('users').add(user);
dispatch({ type: SIGNUP, payload: user });
}
} catch (e) {
alert(e);
}
};
Note how we define the users subcollection:
compRef.collection('users').add(user);
just by calling the collection() method on the company's DocumentReference. This last point is in line with zkohi's answer.