Дата проверки Firestore (значение для аргумента «секунды» должно быть в пределах [-62135596800, 253402300799] включительно)

#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
}