#javascript #firebase #google-cloud-firestore
#javascript #firebase #google-cloud-firestore
Вопрос:
Я делаю пакетную запись в firebase одновременно с созданием пользователя с электронной почтой.
try {
// Get a new Firestore batched write
const batch = firestore.batch();
// Generate an user uuid
const userId = uuidv4();
// Create the new username document in the usernames collection with the user's id as field
const usernameRef = firestore.collection("usernames").doc(username);
batch.set(usernameRef, { userId });
// Create the new user document in the users collection with all the relevant information
const userRef = firestore.collection("users").doc(userId);
// Pass the username to lower case
username = username.toLowerCase();
// Take the birthday milliseconds and convert it back to a Date
birthday = new Date(birthday);
const data = {
email,
username,
name,
birthday,
};
batch.set(userRef, data);
// Create the user with Firebase Authentication
await admin.auth().createUser({
uid: userId,
email,
password,
});
// Commit the batch
await batch.commit();
} catch(err) {
...
}
При этом пользователь не будет добавлен в базу данных, если электронное письмо уже получено. Но есть проблема, если день рождения недействителен для Firestore, исключение будет зафиксировано при пакетной фиксации … поэтому электронное письмо будет зарегистрировано.
Есть ли какой-либо способ проверить значение даты перед передачей его в firestore? Например, если я
birthday = new Date(-182397382409)
это приведет к ошибке.
Значение для аргумента «секунды» должно быть в пределах [-62135596800, 253402300799] включительно
Кроме того, проблема будет решена, если admin.CreateUser также был включен в пакетную запись, но я не знаю, возможно ли это.
Спасибо.
Комментарии:
1. вы могли бы проверить
birthday
2. Дело в том, что firestore autoconvert js датируется {seconds: (не date.getSeconds()) , наносекунды: } объект. И я не знаю, как проверить дату js, чтобы иметь секунды объекта firestore между [-62135596800, 253402300799] включительно.
3. разделить миллисекундную дату js на 1000?
4. @DougStevenson конечно, но в секунду всего 1000 миллисекунд… даты javascript указаны в миллисекундах … приведенный выше код выполняет
birthday = new Date(birthday)
… итак,birthday
(перед преобразованием в объект Date) должно быть в миллисекундах, а не в наносекундах — мое предложение проверялосьbirthday
перед преобразованием его в дату… так что на самом деле нужно было бы убедитьсяbirthday/1000
, что он находится в пределах допустимого диапазона (поскольку"seconds" must be within [-62135596800, 253402300799]
)5. Тогда @JaromandaX звучит как ответ.
Ответ №1:
Чтобы избежать создания пользователя в БД и с помощью электронной почты для аутентификации, я проверяю всю форму клиента, а затем запускаю код в вопросе.
Вот проверка формы
async function validateForm(
username,
email,
password,
repeatPassword,
name,
birthday,
clientIp
) {
... Validate data types, availabilities in the db, regex (including password strength), ...
// Validate the user's birthday
if (!validateBirthday(birthday)) {
return "The birthday is not valid";
}
}
validateBirthday = function (birthday) {
/* Birthday has to be in milliseconds since unix epoch */
// Get the birthday in seconds
const birthdayInSeconds = birthday / 1000;
return birthdayInSeconds >= -62135596800 amp;amp; birthdayInSeconds <= 253402300799
}
Полный код
// Validate the form data
const feedback = await validateForm(
username,
email,
password,
repeatPassword,
name,
birthday,
clientIp
);
// If the form has been validated and no feedback has been received...
if (!feedback) {
try {
// Get a new Firestore batched write
const batch = firestore.batch();
// Generate an user uuid
const userId = uuidv4();
// Create the new username document in the usernames collection with the user's id as field
const usernameRef = firestore.collection("usernames").doc(username);
batch.set(usernameRef, { userId });
// Create the new user document in the users collection with all the relevant information
const userRef = firestore.collection("users").doc(userId);
// Pass the username to lower case
username = username.toLowerCase();
// Take the birthday milliseconds and convert it back to a Date
birthday = new Date(birthday);
const data = {
email,
username,
name,
birthday,
};
batch.set(userRef, data);
// Create the user with Firebase Authentication
await admin.auth().createUser({
uid: userId,
email,
password,
});
// Commit the batch
await batch.commit();
} catch(err) {
...
}
} else {
// Throw feedback to the user
}