40% регистраций пользователей Firebase отсутствуют документы FirestoreJavascript

Форум по Javascript
Ответить
Anonymous
 40% регистраций пользователей Firebase отсутствуют документы Firestore

Сообщение Anonymous »

40% регистраций пользователей Firebase Отсутствие документов Firestore
Я испытываю критическую проблему с моим приложением NextJS/Firebase, где приблизительно 40% случайных регистраций пользователей приводят к «Orphaned» пользователям - пользователи, которые существуют в аутентификации Firebase, но не соответствуют Firestor. Сообщения: < /p>
  • Пользователи на 100% успешно созданы в аутентификации Firebase < /li>
    Но приблизительно 40% попыток случайных регистраций не создают документ Firestore < /li>
    Пользователи не вызывают этого процесса. Форма
  • Эти пользователи не могут получить одобренную регистрацию, одобренные с административной стороны, потому что наше приложение проверяет документы Firestore
Code
здесь функция регистрации пользователя в outcontext.js :
// New user registration
const register = async (email, password, userData) => {
setErrorMessage('');
let user = null;

try {
setLoading(true);

// 1. Create user in Firebase Auth
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
user = userCredential.user;

// 2. Create user document data
const userDocData = {
email: email,
name: userData.name || '',
surname: userData.surname || '',
phone: userData.phone || '',
role: userData.role || 'student',
status: 'pending',
createdAt: serverTimestamp(),
updatedAt: serverTimestamp(),
package: userData.role === 'student' ? {
remainingClasses: 0,
paymentStatus: false
} : null
};

// 3. Create document in Firestore
const batch = writeBatch(db);
batch.set(doc(db, 'users', user.uid), userDocData);
await batch.commit();

// 4. Verify document creation
const checkDoc = await getDoc(doc(db, 'users', user.uid));
if (!checkDoc.exists()) {
throw new Error('User document was not created');
}

// 5. Logout after successful registration
await signOut(auth);

return user;

} catch (error) {
// If Auth user created but Firestore document failed, delete Auth user
if (user) {
try {
// Try to delete any partially created document
try {
await deleteDoc(doc(db, 'users', user.uid));
} catch (docError) {
console.error("Error deleting document:", docError);
}

// Delete Auth user
await deleteUser(user);
} catch (deleteError) {
console.error('Error deleting user after failed registration:', deleteError);
}
}

// Handle specific errors
switch (error.code) {
case 'auth/email-already-in-use':
setErrorMessage('Αυτή η διεύθυνση email χρησιμοποιείται ήδη.');
break;
case 'auth/invalid-email':
setErrorMessage('Μη έγκυρη διεύθυνση email.');
break;
case 'auth/weak-password':
setErrorMessage('Ο κωδικός πρέπει να έχει τουλάχιστον 6 χαρακτήρες.');
break;
default:
setErrorMessage('Σφάλμα κατά την εγγραφή. Παρακαλώ δοκιμάστε ξανά.');
break;
}
throw error;
} finally {
setLoading(false);
}
};
< /code>
Я также попытался реализовать механизм повторной попытки с экспоненциальным отбором: < /p>

Код: Выделить всё

// 3.  Create document with retry mechanism
let success = false;
let attempts = 0;

while (!success && attempts < 5) {
try {
attempts++;
console.log(`Attempt ${attempts} to create Firestore document`);

const batch = writeBatch(db);
batch.set(doc(db, 'users', user.uid), userDocData);
await batch.commit();

// Immediate verification
const checkDoc = await getDoc(doc(db, 'users', user.uid));
if (checkDoc.exists()) {
success = true;
console.log(`Successfully created Firestore document on attempt ${attempts}`);
} else {
console.warn(`Document check failed after batch commit (attempt ${attempts})`);
// Wait before retrying (exponential backoff)
await new Promise(resolve => setTimeout(resolve, 1000 * attempts));
}
} catch (error) {
console.error(`Firestore error on attempt ${attempts}:`, error);
// Wait before retrying
await new Promise(resolve => setTimeout(resolve, 1000 * attempts));
}
}

if (!success) {
throw new Error(`Failed to create Firestore document after ${attempts} attempts`);
}
Я также внедрил временный обходной путь в Onauthstatechanged :

Код: Выделить всё

useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, async (user) => {
if (user) {
try {
// Check if document exists
const userDoc = await getDoc(doc(db, 'users', user.uid));

// If document doesn't exist, create it (fix orphaned users)
if (!userDoc.exists()) {
console.log("Orphaned user detected. Synchronizing...");

await setDoc(doc(db, 'users', user.uid), {
email: user.email,
name: '',
surname: '',
phone: '',
role: 'student',
status: 'pending',
createdAt: serverTimestamp(),
updatedAt: serverTimestamp(),
package: {
remainingClasses: 0,
paymentStatus: false
}
});

// Continue with normal checks...
}
} catch (error) {
console.error('Error fetching user data:', error);
setCurrentUser(null);
}
} else {
setCurrentUser(null);
}
setLoading(false);
});

return () => unsubscribe();
}, [auth, db, router]);
что я попробовал

[*] Использование writebatch вместо setdoc - та же проблема возникает
Добавление механизма повторного повторного периода с до документов - все еще не провалит. /> Добавление надлежащей очистки для удаления пользователей аутентификации -осиротечной аутентификации < /li>
Добавление подробного журнала - без ошибок в журналах, когда возникает проблема < /li>
< /ol>
. /> Использование клиента sdk < /li>
Использование паттерна инициализации с экземпляром Singleton < /li>
< /ul>
Вопрос < /h2>
Что может вызвать это противоречивое поведение, когда пользователи авторов Firebase созданы, но документы Firestore не удастся ~ 40% из времени? Мне нужно надежное решение, так как это влияет на значительную часть наших пользовательских регистраций. Будет ли использование облачных функций Firebase для создания пользователей обеспечить лучшую надежность?


Подробнее здесь: https://stackoverflow.com/questions/797 ... -documents
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»