Erreur "hook call" développement d'application TypeScript

a marqué ce sujet comme résolu.

Bonjour, Je développe une application apple depuis un an maintenant, j’aimerais ajouter l’option de déconnexion pour mes utilisateurs qui ont créé un compte, mais je rencontre de nombreuses erreurs. Quelqu’un saurait-il comment y remédier? Je vous en remercie par avance. Terminal: Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem., js engine: hermes

Le fichier que j’ai modifié avant d’avoir cette erreur:

import React, { useEffect, useState } from 'react';
import { Button, View, Alert } from 'react-native';
import * as WebBrowser from 'expo-web-browser';
import * as Google from 'expo-auth-session/providers/google';
import * as AppleAuthentication from 'expo-apple-authentication';
import { GoogleAuthProvider, OAuthProvider, signInWithCredential, signInAnonymously, reauthenticateWithCredential, deleteUser } from 'firebase/auth';
import { auth } from './Firebase';
import clientId from '../.env/GoogleAuth';
import { digestStringAsync, CryptoDigestAlgorithm } from 'expo-crypto';

WebBrowser.maybeCompleteAuthSession();

const Applenonce = Math.random().toString(36).substring(2, 10);

export const appleConnection = (setDisabled: (disable: boolean) => void) => {
    const [appleCredential, setAppleCredential] = useState(null);

    useEffect(() => {
        if (appleCredential) {
            const { identityToken, email, fullName } = appleCredential;

            const provider = new OAuthProvider('apple.com');
            const credential = provider.credential({
                idToken: identityToken!,
                rawNonce: Applenonce
            });

            signInWithCredential(auth, credential);
            setDisabled(true);
        } else {
            setDisabled(false);
        }
    }, [appleCredential]);

    const signInWithAppleAsync = async () => {
        try {
            const nonce = await digestStringAsync(
                CryptoDigestAlgorithm.SHA256,
                Applenonce
            );
            const appleCredential = await AppleAuthentication.signInAsync({
                requestedScopes: [
                    AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
                    AppleAuthentication.AppleAuthenticationScope.EMAIL,
                ],
                nonce,
            });

            setAppleCredential(appleCredential);
        } catch (e) {
            if (e.code === 'ERR_REQUEST_CANCELED') {
                setAppleCredential(null);
            } else {
                setAppleCredential(null);
            }
        }
    };

    return (signInWithAppleAsync);
}

export const googleConnection = (setDisabled: (disable: boolean) => void) => {
    const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
        ...clientId
    }, {
        projectNameForProxy: "@popoters/slug"
    });

    useEffect(() => {
        if (response?.type === 'success') {
            const { id_token } = response.params;
            const credential = GoogleAuthProvider.credential(id_token);
            signInWithCredential(auth, credential);
        }
        setDisabled(!request || response?.type === 'success');
    }, [response, request]);

    const signInWithGoogleAsync = async () => {
        try {
            const result = await promptAsync();
            if (result.type === 'success') {
                return result.params.id_token;
            } else {
                return { cancelled: true };
            }
        } catch (e) {
            return { error: true };
        }
    };

    return (signInWithGoogleAsync);
}

export const loginAnymously = (setDisabled: (disabled: boolean) => void) => {
    setDisabled(true);
    signInAnonymously(auth)
        .then(() => {
        })
        .catch((error) => {
            alert(error.message);
            setDisabled(false);
        });
}

export const DeleteAppleAccountButton = (setDisabled) => {
    const [loading, setLoading] = useState(false);

    const handleDeleteAccount = async () => {
        setLoading(true);
        try {
            const nonce = await digestStringAsync(
                CryptoDigestAlgorithm.SHA256,
                Applenonce
            );
            const appleCredential = await AppleAuthentication.signInAsync({
                requestedScopes: [
                    AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
                    AppleAuthentication.AppleAuthenticationScope.EMAIL,
                ],
                nonce,
            });

            const { identityToken } = appleCredential;
            const provider = new OAuthProvider('apple.com');
            const credential = provider.credential({
                idToken: identityToken!,
                rawNonce: Applenonce,
            });

            const user = auth.currentUser;
            if (user) {
                await reauthenticateWithCredential(user, credential);
                await deleteUser(user);
                Alert.alert("Compte supprimé avec succès.");
            }
        } catch (e) {
            Alert.alert("Erreur lors de la suppression du compte", e.message);
        } finally {
            setLoading(false);
            setDisabled(false);
        }
    };
}

+0 -0

@viki53 merci pour ta réponse. Est-ce que cette correction te paraît bonne?

import React, { useEffect, useState } from 'react';
import { Button, View, Alert } from 'react-native';
import * as WebBrowser from 'expo-web-browser';
import * as Google from 'expo-auth-session/providers/google';
import * as AppleAuthentication from 'expo-apple-authentication';
import { GoogleAuthProvider, OAuthProvider, signInWithCredential, signInAnonymously, reauthenticateWithCredential, deleteUser } from 'firebase/auth';
import { auth } from './Firebase';
import clientId from '../.env/GoogleAuth';
import { digestStringAsync, CryptoDigestAlgorithm } from 'expo-crypto';

WebBrowser.maybeCompleteAuthSession();

const Applenonce = Math.random().toString(36).substring(2, 10);

export const appleConnection = (setDisabled: (disable: boolean) => void) => {
    const [appleCredential, setAppleCredential] = useState(null);

    useEffect(() => {
        if (appleCredential) {
            const { identityToken, email, fullName } = appleCredential;

            const provider = new OAuthProvider('apple.com');
            const credential = provider.credential({
                idToken: identityToken!,
                rawNonce: Applenonce
            });

            signInWithCredential(auth, credential);
            setDisabled(true);
        } else {
            setDisabled(false);
        }
    }, [appleCredential]);

    const signInWithAppleAsync = async () => {
        try {
            const nonce = await digestStringAsync(
                CryptoDigestAlgorithm.SHA256,
                Applenonce
            );
            const appleCredential = await AppleAuthentication.signInAsync({
                requestedScopes: [
                    AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
                    AppleAuthentication.AppleAuthenticationScope.EMAIL,
                ],
                nonce,
            });

            setAppleCredential(appleCredential);
        } catch (e) {
            if (e.code === 'ERR_REQUEST_CANCELED') {
                setAppleCredential(null);
            } else {
                setAppleCredential(null);
            }
        }
    };

    return (signInWithAppleAsync);
}

export const googleConnection = (setDisabled: (disable: boolean) => void) => {
    const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
        ...clientId
    }, {
        projectNameForProxy: "@popoters/slug"
    });

    useEffect(() => {
        if (response?.type === 'success') {
            const { id_token } = response.params;
            const credential = GoogleAuthProvider.credential(id_token);
            signInWithCredential(auth, credential);
        }
        setDisabled(!request || response?.type === 'success');
    }, [response, request]);

    const signInWithGoogleAsync = async () => {
        try {
            const result = await promptAsync();
            if (result.type === 'success') {
                return result.params.id_token;
            } else {
                return { cancelled: true };
            }
        } catch (e) {
            return { error: true };
        }
    };

    return (signInWithGoogleAsync);
}

export const loginAnymously = (setDisabled: (disabled: boolean) => void) => {
    setDisabled(true);
    signInAnonymously(auth)
        .then(() => {
        })
        .catch((error) => {
            alert(error.message);
            setDisabled(false);
        });
}

const ParentComponent: React.FC = () => {
    const [loading, setLoading] = useState(false);
    const [disabled, setDisabled] = useState(false);

    // Déplacez la logique de suppression ici
    const handleDeleteAccount = async () => {
        setLoading(true);
        setDisabled(true);
        try {
            const nonce = await digestStringAsync(
                CryptoDigestAlgorithm.SHA256,
                Applenonce
            );
            const appleCredential = await AppleAuthentication.signInAsync({
                requestedScopes: [
                    AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
                    AppleAuthentication.AppleAuthenticationScope.EMAIL,
                ],
                nonce,
            });

            const { identityToken } = appleCredential;
            const provider = new OAuthProvider('apple.com');
            const credential = provider.credential({
                idToken: identityToken!,
                rawNonce: Applenonce,
            });

            const user = auth.currentUser;
            if (user) {
                await reauthenticateWithCredential(user, credential);
                await deleteUser(user);
                Alert.alert("Compte supprimé avec succès.");
            }
        } catch (e) {
            Alert.alert("Erreur lors de la suppression du compte", e.message);
        } finally {
            setLoading(false);
            setDisabled(false);
        }
    };

    return (
        <View>
            {/* Vous pouvez appeler la fonction handleDeleteAccount ici ou la passer à un composant enfant */}
            <Button
                onPress={handleDeleteAccount}
                title={loading ? "Suppression en cours..." : "Supprimer mon compte Apple"}
                disabled={loading || disabled}
            />
        </View>
    );
};

export default ParentComponent;

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte