Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Invalid hook call" error #42

Open
ycdaskin opened this issue Apr 20, 2023 · 4 comments
Open

"Invalid hook call" error #42

ycdaskin opened this issue Apr 20, 2023 · 4 comments

Comments

@ycdaskin
Copy link

When i try to run very basic example given in the readme doc, i am facing invalid hook call error.

My code is:

import { useEffect } from "react";
import { Text, View } from "react-native";
import { useTwitter } from "react-native-simple-twitter";

const TwitterSignin = () => {
    
    const { twitter, TWModal, loggedInUser, accessToken } = useTwitter({
        consumerKey: "my key",
        consumerSecret: "my secret",
    });

    const onLoginPress = async () => {
        try {
            await twitter.login();
        } catch (e) {
            console.log(e.errors);
        }
    }
    

    useEffect(() => {
        console.log(loggedInUser)
    }, [loggedInUser, accessToken]);

    return (
        <View>
            <Text onPress={onLoginPress}>login</Text>
            <TWModal />
        </View>
    )
}

export default TwitterSignin

image

react native version: 0.71.6

@AlbertJohanson
Copy link

Did you find a way to solve this?

@ycdaskin
Copy link
Author

no. i am not using this library anymore. i am not using any libraries tho. i solved it by using twitter rest api. it was a little bit hard to understand at the beginning but now i have a pure js and no dependency solution.

@Fardeen-Niyazi
Copy link

@ycdaskin can you please provide the code

@ycdaskin
Copy link
Author

const TwitterSignup = ({ navigation }) => {

    const CONSUMER_KEY = 'Your consumer key / api key';
    const CONSUMER_SECRET = 'your consumer secret key / api secret key';
    let ACCESS_TOKEN = ''; // We will use it later
    let ACCESS_TOKEN_SECRET = ''; // We will use it later


    const [loading, setLoading] = useState(false)


    useEffect(() => {
        Linking.addEventListener('url', handleOpenURL);
        return () => Linking.removeEventListener('url', handleOpenURL);
    }, [])

   
    const handleOpenURL = (event) => {
        // You have to set your callback url on your twitter developer account page. It must be a deeplink that redirects to your app. there will be some additional steps for android and ios. yo can find them easly by googling
        handleTwitterCallback(event);
    }

    // these are some helper functions
    const generateNonce = () => {
        return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
    }

    const generateTimestamp = () => {
        return Math.floor(Date.now() / 1000);
    }

    const generateBaseString = (method, url, params) => {
        const parameterString = Object.keys(params)
            .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
            .join('&');

        return `${method}&${encodeURIComponent(url)}&${encodeURIComponent(parameterString)}`;
    }

    const generateSigningKey = (consumerSecret, tokenSecret) => {
        return `${encodeURIComponent(consumerSecret)}&${encodeURIComponent(tokenSecret)}`;
    }

    const generateOAuthSignature = (baseString, signingKey) => {
        const signature = CryptoJS.HmacSHA1(baseString, signingKey).toString(CryptoJS.enc.Base64);
        return encodeURIComponent(signature);
    }

    const generateAuthorizationHeader = (params) => {
        const headerParams = Object.keys(params)
            .map((key) => `${key}="${params[key]}"`)
            .join(', ');

        return `OAuth ${headerParams}`;
    }

    async function getRequestToken() {
        const requestTokenURL = 'https://api.twitter.com/oauth/request_token';
        const callbackURL = 'yourapp://oauth-callback'; // callback url comes here. it must be something like this example
        const oauthSignatureMethod = 'HMAC-SHA1';
        const oauthVersion = '1.0';

        const oauthNonce = generateNonce();
        const oauthTimestamp = generateTimestamp();

        const oauthParams = {
            oauth_callback: callbackURL,
            oauth_consumer_key: CONSUMER_KEY,
            oauth_nonce: oauthNonce,
            oauth_signature_method: oauthSignatureMethod,
            oauth_timestamp: oauthTimestamp,
            oauth_version: oauthVersion,
        };

        // order OAuth params and sign
        const orderedParams = Object.keys(oauthParams)
            .sort()
            .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(oauthParams[key])}`)
            .join('&');

        const baseString = `POST&${encodeURIComponent(requestTokenURL)}&${encodeURIComponent(orderedParams)}`;

        const signingKey = `${encodeURIComponent(CONSUMER_SECRET)}&`;

        const oauthSignature = CryptoJS.HmacSHA1(baseString, signingKey).toString(CryptoJS.enc.Base64);

        // create Authorization header 
        const authorizationHeader = `OAuth oauth_callback="${encodeURIComponent(callbackURL)}", oauth_consumer_key="${CONSUMER_KEY}", oauth_nonce="${oauthNonce}", oauth_signature="${encodeURIComponent(oauthSignature)}", oauth_signature_method="${oauthSignatureMethod}", oauth_timestamp="${oauthTimestamp}", oauth_version="${oauthVersion}"`;

        try {
            const response = await axios(requestTokenURL, {
                method: 'POST',
                headers: {
                    Authorization: authorizationHeader
                }
            });
            const responseData = response.data;
            const requestToken = responseData.match(/oauth_token=([^&]+)/)[1];

            // now redirect user to twitter login screen
            const twitterLoginURL = `https://api.twitter.com/oauth/authenticate?oauth_token=${requestToken}`;
            Linking.openURL(twitterLoginURL);
        } catch (error) {
            console.error('Request Token alınamadı:', error);
        }
    }


   

    const handleTwitterCallback = async (event) => {
        const url = event.url;

        const params = url.split('?')[1];
        const tokenParts = params.split('&');
        const requestToken = tokenParts[0].split('=')[1];
        const oauthVerifier = tokenParts[1].split('=')[1];


        const accessTokenURL = 'https://api.twitter.com/oauth/access_token';
        const method = 'POST';
        const oauthNonce = generateNonce();
        const oauthTimestamp = generateTimestamp();
        const oauthSignatureMethod = 'HMAC-SHA1';
        const oauthVersion = '1.0';

        const baseString = generateBaseString(method, accessTokenURL, {
            oauth_consumer_key: CONSUMER_KEY,
            oauth_nonce: oauthNonce,
            oauth_signature_method: oauthSignatureMethod,
            oauth_timestamp: oauthTimestamp,
            oauth_token: requestToken,
            oauth_verifier: oauthVerifier,
            oauth_version: oauthVersion,
        });

        const signingKey = generateSigningKey(CONSUMER_SECRET, '');
        const oauthSignature = generateOAuthSignature(baseString, signingKey);

        const headers = {
            Authorization: generateAuthorizationHeader({
                oauth_consumer_key: CONSUMER_KEY,
                oauth_nonce: oauthNonce,
                oauth_signature: oauthSignature,
                oauth_signature_method: oauthSignatureMethod,
                oauth_timestamp: oauthTimestamp,
                oauth_token: requestToken,
                oauth_verifier: oauthVerifier,
                oauth_version: oauthVersion,
            }),
        };

        try {
            const response = await axios.post(accessTokenURL, null, { headers });
            const responseData = response.data;
            const userAccessToken = responseData.match(/oauth_token=([^&]+)/)[1];
            const userAccessTokenSecret = responseData.match(/oauth_token_secret=([^&]+)/)[1];

            ACCESS_TOKEN = userAccessToken;
            ACCESS_TOKEN_SECRET = userAccessTokenSecret;

            //User authenticatedı, now we can get user information
            const userInfo = await getUserInfo();

            // now we have use user info. we can use it as we want
            console.log('User info:', userInfo);
            

        } catch (error) {
            console.error('Access Token alınamadı:', error);
        }
    }

    const getUserInfo = async () => {
        const verifyCredentialsURL = 'https://api.twitter.com/1.1/account/verify_credentials.json';
        const method = 'GET';
        const oauthNonce = generateNonce();
        const oauthTimestamp = generateTimestamp();
        const oauthSignatureMethod = 'HMAC-SHA1';
        const oauthVersion = '1.0';

        const baseString = generateBaseString(method, verifyCredentialsURL, {
            oauth_consumer_key: CONSUMER_KEY,
            oauth_nonce: oauthNonce,
            oauth_signature_method: oauthSignatureMethod,
            oauth_timestamp: oauthTimestamp,
            oauth_token: ACCESS_TOKEN,
            oauth_version: oauthVersion,
        });

        const signingKey = generateSigningKey(CONSUMER_SECRET, ACCESS_TOKEN_SECRET);
        const oauthSignature = generateOAuthSignature(baseString, signingKey);

        const headers = {
            Authorization: generateAuthorizationHeader({
                oauth_consumer_key: CONSUMER_KEY,
                oauth_nonce: oauthNonce,
                oauth_signature: oauthSignature,
                oauth_signature_method: oauthSignatureMethod,
                oauth_timestamp: oauthTimestamp,
                oauth_token: ACCESS_TOKEN,
                oauth_version: oauthVersion,
            }),
        };

        try {
            const response = await axios.get(verifyCredentialsURL, { headers });

            // you can print entire response.data object to see what information is coming
            const { id, name, screen_name, profile_image_url_https } = response.data;
            return { id, name, screen_name, profile_image_url_https };
        } catch (error) {
            console.error('Kullanıcı bilgileri alınamadı:', error);
        }
    }






    return (
        <SafeAreaView style={{ flex: 1, }}>
            <View
                style={{
                    flex: 1,
                    paddingTop: Platform.OS === "android" ? 20 : 0,
                    padding: 20
                }}
            >
                <Header
                    title={"Twitter Login"}
                    buttonBehavior="back"
                    onBackPress={() => navigation.goBack()}
                    colors={colors}
                />
                <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>

                    <TouchableOpacity
                        style={{
                            ...styles.ssoButton,
                            borderColor: colors.text01
                        }}
                        onPress={getRequestToken}
                        disabled={loading}
                    >
                        <SvgFromXml
                            xml={TwitterIcon}
                        />
                        {loading ? (
                            <ActivityIndicator />
                        ) : (
                            <Text
                                style={{
                                    ...styles.text,
                                    color: colors.text
                                }}
                            >
                                {"Login with Twitter"}
                            </Text>
                        )}

                    </TouchableOpacity>
                </View>
            </View>
        </SafeAreaView>
    );
}


export default TwitterSignup;


const styles = StyleSheet.create({
    ssoButton: {
        flexDirection: 'row',
        height: 56,
        marginRight: 16,
        borderRadius: 28,
        borderWidth: .5,
        alignItems: 'center',
        paddingRight: 20,
        paddingLeft: 20
    },
    text: {
        fontFamily: globalStyles.fontMedium,
        fontSize: 16,
        marginLeft: 8,
    }
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants