Поддерживает ли expo аутентификацию по телефону с помощью firebase?

Я пытаюсь реализовать аутентификацию телефона firebase для expo. Я следил за многими ресурсами в Интернете, но мне это удалось. Не могли бы вы сообщить мне, возможно ли это / доступно? если есть возможность, поделитесь, пожалуйста, некоторыми полезными ресурсами для выставки

спасибо за ожидание.

У тебя есть решение? @ Imdad Hussain

Nivesh 05.10.2018 11:29

Ребята, просто пользуйтесь Flutter и будьте счастливы). Это действительно отличный инструмент. Я использую его около полугода, и не было проблем, которые Flutter не может решить.

Rinat 06.08.2019 08:17
Интеграция Angular - Firebase Analytics
Интеграция Angular - Firebase Analytics
Узнайте, как настроить Firebase Analytics и отслеживать поведение пользователей в вашем приложении Angular.
3
2
5 388
6

Ответы 6

У меня была такая же проблема, но я нашел решение. Итак, как это работает:

  1. У нас есть специальная статическая веб-страница «Captcha», размещенная в домене, авторизованном в нашем проекте Firebase. Просто показывает firebase.auth.RecaptchaVerifier. Пользователь разрешает капчу, и она выдает строку token из ответа обратного вызова.

  2. На экране входа в приложение мы показываем WebBrowser со страницей «Captcha» и прослушиваем событие изменения URL-адреса методами Linking. На новом url мы извлекаем из него строку токена.

  3. Затем мы создаем поддельный объект firebase.auth.ApplicationVerifier с помощью token и передаем его firebase.auth().signInWithPhoneNumber (с номером телефона). SMS-код будет отправлен.

Ниже я написал проверенный простейший код. Вы можете напрямую "скопировать-вставить" его. Просто добавьте конфигурацию firebase (эта конфигурация должна быть одинаковой для обоих) и установите правильный URL страницы "Captcha". Не забывайте, что номер телефона должен быть указан в международном формате. В этом коде страница «Captcha» размещена на хостинге firebase, поэтому она автоматически инициализируется путем включения init.js и авторизуется по умолчанию.

Страница "Captcha" (размещен на хостинге firebase):

<!DOCTYPE html>
<html lang = "ru">
<head>
    <meta charset = "UTF-8">
    <meta name = "viewport" content = "width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <title>Entering captcha</title>
</head>
<body>
    <p style = "text-align: center; font-size: 1.2em;">Please, enter captcha for continue<p/>

    <script src = "/__/firebase/5.3.1/firebase-app.js"></script>
    <script src = "/__/firebase/5.3.1/firebase-auth.js"></script>
    <script src = "/__/firebase/init.js"></script>
    <script>

        function getToken(callback) {
            var container = document.createElement('div');
            container.id = 'captcha';
            document.body.appendChild(container);
            var captcha = new firebase.auth.RecaptchaVerifier('captcha', {
                'size': 'normal',
                'callback': function(token) {
                    callback(token);
                },
                'expired-callback': function() {
                    callback('');
                }
            });
            captcha.render().then(function() {
                captcha.verify();
            });
        }

        function sendTokenToApp(token) {
            var baseUri = decodeURIComponent(location.search.replace(/^\?appurl\=/, ''));
            location.href = baseUri + '/?token=' + encodeURIComponent(token);
        }

        document.addEventListener('DOMContentLoaded', function() {
            getToken(sendTokenToApp);
        });

    </script>
</body>
</html>

Экран авторизации в выставочном проекте:

import * as React from 'react'
import {Text, View, ScrollView, TextInput, Button} from 'react-native'
import {Linking, WebBrowser} from 'expo'
import firebase from 'firebase/app'
import 'firebase/auth'

const captchaUrl = `https://my-firebase-hosting/captcha-page.html?appurl=${Linking.makeUrl('')}`

firebase.initializeApp({
    //firebase config
});

export default class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            user: undefined,
            phone: '',
            confirmationResult: undefined,
            code: ''
        }
        firebase.auth().onAuthStateChanged(user => {
            this.setState({user})
        })
    }

    onPhoneChange = (phone) => {
        this.setState({phone})
    }
    onPhoneComplete = async () => {
        let token = null
        const listener = ({url}) => {
            WebBrowser.dismissBrowser()
            const tokenEncoded = Linking.parse(url).queryParams['token']
            if (tokenEncoded)
                token = decodeURIComponent(tokenEncoded)
        }
        Linking.addEventListener('url', listener)
        await WebBrowser.openBrowserAsync(captchaUrl)
        Linking.removeEventListener('url', listener)
        if (token) {
            const {phone} = this.state
            //fake firebase.auth.ApplicationVerifier
            const captchaVerifier = {
                type: 'recaptcha',
                verify: () => Promise.resolve(token)
            }
            try {
                const confirmationResult = await firebase.auth().signInWithPhoneNumber(phone, captchaVerifier)
                this.setState({confirmationResult})
            } catch (e) {
                console.warn(e)
            }

        }
    }
    onCodeChange = (code) => {
        this.setState({code})
    }
    onSignIn = async () => {
        const {confirmationResult, code} = this.state
        try {
            await confirmationResult.confirm(code)
        } catch (e) {
            console.warn(e)
        }
        this.reset()
    }
    onSignOut = async () => {
        try {
            await firebase.auth().signOut()
        } catch (e) {
            console.warn(e)
        }
    }
    reset = () => {
        this.setState({
            phone: '',
            phoneCompleted: false,
            confirmationResult: undefined,
            code: ''
        })
    }

    render() {
        if (this.state.user)
            return (
                <ScrollView style = {{padding: 20, marginTop: 20}}>
                    <Text>You signed in</Text>
                    <Button
                        onPress = {this.onSignOut}
                        title = "Sign out"
                    />
                </ScrollView>
            )

        if (!this.state.confirmationResult)
            return (
                <ScrollView style = {{padding: 20, marginTop: 20}}>
                    <TextInput
                        value = {this.state.phone}
                        onChangeText = {this.onPhoneChange}
                        keyboardType = "phone-pad"
                        placeholder = "Your phone"
                    />
                    <Button
                        onPress = {this.onPhoneComplete}
                        title = "Next"
                    />
                </ScrollView>
            )
        else
            return (
                <ScrollView style = {{padding: 20, marginTop: 20}}>
                    <TextInput
                        value = {this.state.code}
                        onChangeText = {this.onCodeChange}
                        keyboardType = "numeric"
                        placeholder = "Code from SMS"
                    />
                    <Button
                        onPress = {this.onSignIn}
                        title = "Sign in"
                    />
                </ScrollView>
            )
    }
}

Будет ли страница с капчей автоматически закрываться после того, как пользователь выполнит проверку?

iAviator 30.09.2018 17:34

@iAviator, да. Captcha вызывает callback или expired-callback, затем перенаправляет страницы, устанавливая location.href, наконец, это изменение URL-адреса обнаруживается функцией прослушивателя (Linking.addEventListener('url', listener))

Rinat 01.10.2018 14:18

Хорошо .. также, как можно реализовать невидимую капчу в react native, где я хочу, чтобы пользователь был проверен без какого-либо взаимодействия на экране?

iAviator 04.10.2018 19:08

В любом случае модальный экран WebBrowser необходимо отображать, потому что он дает строку токена. Можно попробовать поэкспериментировать с режимами рекапчи firebase.google.com/docs/auth/web/…

Rinat 04.10.2018 21:28

Проблема, с которой я столкнулся сейчас, заключается в том, что на экране веб-браузера иногда не отображается сетка проверочных изображений, а отображается только флажок recaptcha.

iAviator 06.10.2018 14:06

хм, никогда не сталкивался с этим. какая модель устройства?

Rinat 09.10.2018 00:37

Всплывающее окно не закрывается, оно было на index.html хостинга firebase, я меняю его на captcha.html, и теперь он работает

Emmanuel Orozco 23.11.2018 20:15

@Rinat Значит, это работает в iOS, но не в Android. В андроиде поп не закрывается. Удалось заставить его работать в Android?

Emmanuel Orozco 26.11.2018 17:43

поддельный firebase.auth.ApplicationVerifier больше не работает. Я вижу это сообщение об ошибке: Ошибка: реализация firebase.auth.ApplicationVerifier.prototype.verify () должна возвращать firebase.Promise, которая разрешается с помощью строки.

boygiandi 26.02.2019 16:30

@boygiandi, какую версию firebase вы используете? возможно, вам поможет понижение версии (например, до 5.3.1), или вы можете попробовать вернуть собственный объект обещания firebase вместо встроенного обещания (исправив его там: () => Promise.resolve(token))

Rinat 27.02.2019 11:14

Это сработало хорошо, когда я загрузил ваш проект и изменил URL-адрес captcha. В моем проекте я связал реагировать и реагировать на тот же проект firebase. Поэтому я разместил одностраничное приложение. Мой вопрос: где я размещаю captcha.html?

Arjun sr 11.03.2020 08:02

Вышеупомянутая проблема была решена. Он хорошо работал на expo client. Он работал хорошо, когда я публиковал на expo. Но когда я создаю файл apk и устанавливаю его на реальном устройстве, приложение внезапно закрывается, показывая ошибку глубокой ссылки без пользовательской схемы. добавлена ​​«схема»: 'myapp' в файле app.json. Теперь приложение открывается, страница captacha загружается после того, как я поставил галочку, она переходит в мое приложение, но загружает поле для ввода номера мобильного телефона с номером мобильного телефона, который я уже добавил. Я получаю otp из firebase, но поле номера телефона загружается вместе с полем ввода otp.

Arjun sr 19.03.2020 12:18

Хорошо @ Ответ Рината был почти идеальным.

Проблема с этой функцией на странице капчи

function sendTokenToApp(token) {
  var baseUri = decodeURIComponent(location.search.replace(/^\?appurl\=/, ''));
  location.href = baseUri + '/?token=' + encodeURIComponent(token);
}

Работает с iOS (Safary), но оказывается, что Chrome не позволяет

location.href

настраиваемых URL-адресов (мы пытались перенаправить пользователя на настраиваемый URL-адрес, exp: //192.12.12.31)

Итак, это новая функция:

function sendTokenToApp(token) {
            var baseUri = decodeURIComponent(location.search.replace(/^\?appurl\=/, ''));
            const finalUrl = location.href = baseUri + '/?token=' + encodeURIComponent(token);
            const continueBtn = document.querySelector('#continue-btn');
            continueBtn.onclick = (event)=>{
                window.open(finalUrl,'_blank')
            }
            continueBtn.style.display = "block";
}

Конечно, вам нужно добавить кнопку в HTML, чтобы вы могли щелкнуть по ней.

Это полный код:

<!DOCTYPE html>
<html lang = "ru">
<head>
    <meta charset = "UTF-8">
    <meta name = "viewport" content = "width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <title>Entering captcha</title>
</head>
<body>
    <p style = "text-align: center; font-size: 1.2em;">Please, enter captcha for continue<p/>
    <button id = "continue-btn" style = "display:none">Continue to app</button>

    <script src = "/__/firebase/5.3.1/firebase-app.js"></script>
    <script src = "/__/firebase/5.3.1/firebase-auth.js"></script>
    <script src = "/__/firebase/init.js"></script>
    <script>

        function getToken(callback) {
            var container = document.createElement('div');
            container.id = 'captcha';
            document.body.appendChild(container);
            var captcha = new firebase.auth.RecaptchaVerifier('captcha', {
                'size': 'normal',
                'callback': function(token) {
                    callback(token);
                },
                'expired-callback': function() {
                    callback('');
                }
            });
            captcha.render().then(function() {
                captcha.verify();
            });
        }

        function sendTokenToApp(token) {
            var baseUri = decodeURIComponent(location.search.replace(/^\?appurl\=/, ''));
            const finalUrl = location.href = baseUri + '/?token=' + encodeURIComponent(token);
            const continueBtn = document.querySelector('#continue-btn');
            continueBtn.onclick = (event)=>{
                window.open(finalUrl,'_blank')
            }
            continueBtn.style.display = "block";
        }

        document.addEventListener('DOMContentLoaded', function() {
            getToken(sendTokenToApp);
        });

    </script>
</body>
</html>

На это у меня ушло почти 7 часов, так что я надеюсь, что это кому-то поможет!

Редактировать после производства:

Не забудьте добавить "scheme": "appName" в app.json приложения expo или браузера, который не открывается из-за проблемы с глубокими ссылками.

Прочитайте это

https://docs.expo.io/versions/latest/workflow/linking#in-a-standalone-app

Вот мое решение, основанное на решении @Rinat. Основная проблема с предыдущим кодом заключается в том, что firebase.auth().signInWithPhoneNumber никогда не запускается, поскольку он не находится в webView, а firebase> 6.3.3 требует действительного домена для аутентификации. Я решил использовать React Native Webview, чтобы упростить обмен данными между WebView и Native.

React-Native сторона

import React from 'react'
import { KeyboardAvoidingView  } from 'react-native';
import { TextInput, Button } from 'react-native-paper';
import { WebView } from 'react-native-webview';

import firebase from 'firebase/app';
import 'firebase/auth';

firebase.initializeApp({
    //...your firebase config
});

const captchaUrl = 'https://yourfirebasehosting/captcha.html';

export default class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            phoneNumber: '',
            phoneSubmitted: false,
            promptSmsCode: false,
            smsCode: '',
            smsCodeSubmitted: false
        }
        firebase.auth().onAuthStateChanged(this.onAuthStateChanged);
    }

    onAuthStateChanged = async user => {
        if (user) {
            const token = await firebase.auth().currentUser.getIdToken();
            if (token) {
                // User is fully logged in, with JWT in token variable
            }
        }
    }

    updatePhoneNumber = phoneNumber => this.setState({phoneNumber});
    updateSmsCode = smsCode => this.setState({smsCode});

    onSubmitPhoneNumber = () => this.setState({phoneSubmitted: true});

    onGetMessage = async event => {
        const { phoneNumber } = this.state;
        const message = event.nativeEvent.data;

        switch (message) {
            case "DOMLoaded":
                this.webviewRef.injectJavaScript(`getToken('${phoneNumber}')`);
                return;
            case "ErrorSmsCode":
                // SMS Not sent or Captcha verification failed. You can do whatever you want here
                return;
            case "":
                return;
            default: {
                this.setState({
                    promptSmsCode: true,
                    verificationId: message,
                })
            }
        }
    }

    onSignIn = async () => {
        this.setState({smsCodeSubmitted: true});
        const { smsCode, verificationId } = this.state;
        const credential = firebase.auth.PhoneAuthProvider.credential(verificationId, smsCode);
        firebase.auth().signInWithCredential(credential);
    }

    render() {

        const { phoneSubmitted, phoneNumber, promptSmsCode, smsCode, smsCodeSubmitted } = this.state;

        if (!phoneSubmitted) return (
            <KeyboardAvoidingView style = {styles.container} behavior = "padding" enabled>
                <TextInput
                    label='Phone Number'
                    value = {phoneNumber}
                    onChangeText = {this.updatePhoneNumber}
                    mode = "outlined"
                />
                <Button mode = "contained" onPress = {this.onSubmitPhoneNumber}>
                    Send me the code!
                </Button>
            </KeyboardAvoidingView >
        );

        if (!promptSmsCode) return (
            <WebView
                ref = {r => (this.webviewRef = r)}
                source = {{ uri: captchaUrl }}
                onMessage = {this.onGetMessage}
            />
        )

        return (
            <KeyboardAvoidingView style = {styles.container} behavior = "padding" enabled>
                <TextInput
                    label='Verification code'
                    value = {smsCode}
                    onChangeText = {this.updateSmsCode}
                    mode = "outlined"
                    disabled = {smsCodeSubmitted}
                    keyboardType='numeric'
                />
                <Button mode = "contained" onPress = {this.onSignIn} disabled = {smsCodeSubmitted}>
                    Send
                </Button>
            </KeyboardAvoidingView >
        );
    }
}

captcha.html

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <meta name = "viewport" content = "width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <title>Entering captcha</title>
</head>
<body>
    <script src = "/__/firebase/6.3.3/firebase-app.js"></script>
    <script src = "/__/firebase/6.3.3/firebase-auth.js"></script>
    <script src = "/__/firebase/init.js"></script>
    <script>
        function getToken(phoneNumber) {
            var container = document.createElement('div');
            container.id = 'captcha';
            document.body.appendChild(container);
            window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('captcha', {
                'size': 'normal',
                'callback': function(response) {
                    var appVerifier = window.recaptchaVerifier;
                    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
                        .then(function (confirmationResult) {
                            window.ReactNativeWebView.postMessage(confirmationResult.verificationId);
                        }).catch(function (error) {
                            window.ReactNativeWebView.postMessage('ErrorSmsCode');
                        });
                }
            });

            window.recaptchaVerifier.render().then(function() {
                window.recaptchaVerifier.verify();
            });
        }

        document.addEventListener('DOMContentLoaded', function() {
            window.ReactNativeWebView.postMessage('DOMLoaded');
        });

    </script>
</body>
</html>

Привет, спасибо за решения .. Сработало для меня .. Но для лучшего способа мы можем пропустить капчу, добавив невидимый верификатор капчи.

// Реагировать на нативную сторону

     import * as React from 'react'
    import { View, ScrollView, TextInput, Button, StyleSheet, WebView } from 'react-native';
    import { Text } from "galio-framework";
    import { Linking } from 'expo';
    import * as firebase from 'firebase';
    import OTPInputView from '@twotalltotems/react-native-otp-input'
    import theme from '../constants/Theme';

    const captchaUrl = `your firebase host /index.html?appurl=${Linking.makeUrl('')}`

    firebase.initializeApp({
        //firebase config

    });

    export default class PhoneAUth extends React.Component {
        constructor(props) {
            super(props)
            this.state = {
                user: undefined,
                phone: '',
                confirmationResult: undefined,
                code: '',
                isWebView: false
            }
            firebase.auth().onAuthStateChanged(user => {
                this.setState({ user })
            })
        }

    onPhoneChange = (phone) => {
        this.setState({ phone })
    }
    _onNavigationStateChange(webViewState) {
        console.info(webViewState.url)
        this.onPhoneComplete(webViewState.url)
    }
    onPhoneComplete = async (url) => {
        let token = null
        console.info("ok");
        //WebBrowser.dismissBrowser()
        const tokenEncoded = Linking.parse(url).queryParams['token']
        if (tokenEncoded)
            token = decodeURIComponent(tokenEncoded)

        this.verifyCaptchaSendSms(token);


    }
    verifyCaptchaSendSms = async (token) => {
        if (token) {
            const { phone } = this.state
            //fake firebase.auth.ApplicationVerifier
            const captchaVerifier = {
                type: 'recaptcha',
                verify: () => Promise.resolve(token)
            }
            try {
                const confirmationResult = await firebase.auth().signInWithPhoneNumber(phone, captchaVerifier)
                console.info("confirmationResult" + JSON.stringify(confirmationResult));
                this.setState({ confirmationResult, isWebView: false })
            } catch (e) {
                console.warn(e)
            }

        }
    }

    onSignIn = async (code) => {
        const { confirmationResult } = this.state
        try {
            const result = await confirmationResult.confirm(code);
            this.setState({ result });

        } catch (e) {
            console.warn(e)

        }
    }
    onSignOut = async () => {
        try {
            await firebase.auth().signOut()
        } catch (e) {
            console.warn(e)
        }
    }
    reset = () => {
        this.setState({
            phone: '',
            phoneCompleted: false,
            confirmationResult: undefined,
            code: ''
        })
    }

    render() {
    if (this.state.user)
        return (
            <ScrollView style = {{padding: 20, marginTop: 20}}>
                <Text>You signed in</Text>
                <Button
                    onPress = {this.onSignOut}
                    title = "Sign out"
                />
            </ScrollView>
        )
        else if (this.state.isWebView)
            return (
                <WebView
                    ref = "webview"
                    source = {{ uri: captchaUrl }}
                    onNavigationStateChange = {this._onNavigationStateChange.bind(this)}
                    javaScriptEnabled = {true}
                    domStorageEnabled = {true}
                    injectedJavaScript = {this.state.cookie}
                    startInLoadingState = {false}
                />

            )
        else if (!this.state.confirmationResult)
            return (
                <ScrollView style = {{ padding: 20, marginTop: 20 }}>
                    <TextInput
                        value = {this.state.phone}
                        onChangeText = {this.onPhoneChange}
                        keyboardType = "phone-pad"
                        placeholder = "Your phone"
                    />
                    <Button
                        onPress = {this.onPhoneComplete}
                        title = "Next"
                    />
                </ScrollView>
            )
        else
            return (
                <ScrollView style = {{padding: 20, marginTop: 20}}>
                    <TextInput
                        value = {this.state.code}
                        onChangeText = {this.onCodeChange}
                        keyboardType = "numeric"
                        placeholder = "Code from SMS"
                    />
                    <Button
                        onPress = {this.onSignIn}
                        title = "Sign in"
                    />
                </ScrollView>
            )
    }
}
const styles = StyleSheet.create({
    borderStyleBase: {
        width: 30,
        height: 45
    },

    borderStyleHighLighted: {
        borderColor: theme.COLORS.PRIMARY,
    },

    underlineStyleBase: {
        width: 30,
        height: 45,
        borderWidth: 0,
        borderBottomWidth: 1,
    },

    underlineStyleHighLighted: {
        borderColor: theme.COLORS.PRIMARY,
    },
});

// Сторона капчи. Я использовал хостинг Firebase для размещения этого файла

<!DOCTYPE html>
<html lang = "en">

<head>
    <meta charset = "UTF-8">
    <title>Firebase Phone Authentication</title>
    <meta name = "viewport" content = "width=device-width, initial-scale=1.0, maximum-scale=1.0">

    <script src = "https://www.gstatic.com/firebasejs/4.3.1/firebase.js"></script>
    <script>
        // Your web app's Firebase configuration
        var firebaseConfig = {
    // config
        };
        // Initialize Firebase
        firebase.initializeApp(firebaseConfig);
    </script>
    <script src = "https://cdn.firebase.com/libs/firebaseui/2.3.0/firebaseui.js"></script>
    <link type = "text/css" rel = "stylesheet" href = "https://cdn.firebase.com/libs/firebaseui/2.3.0/firebaseui.css" />
    <link href = "style.css" rel = "stylesheet" type = "text/css" media = "screen" />

</head>

<body>
    <script>

        function getToken(callback) {
            var container = document.createElement('div');
            container.id = 'captcha';
            document.body.appendChild(container);
            var captcha = new firebase.auth.RecaptchaVerifier('captcha', {

        /****************
         I N V I S I B L E  
        **********************/
                'size': 'invisible',
                'callback': function (token) {
                    callback(token);
                },
                'expired-callback': function () {
                    callback('');
                }
            });
            captcha.render().then(function () {
                captcha.verify();
            });
        }

        function sendTokenToApp(token) {
            var baseUri = decodeURIComponent(location.search.replace(/^\?appurl\=/, ''));
            location.href = 'http://www.google.com + '/?token=' + encodeURIComponent(token);
        }

        document.addEventListener('DOMContentLoaded', function () {
            getToken(sendTokenToApp);
        });

    </script>
    <h2>Verification Code is Sending !! </h2>
    <h3>Please Wait !!</h3>

</body>

</html>

В Android уволить веб-браузер не поддерживает. Итак, я нашел более лучший способ, используя веб-просмотр, он работал у меня на Android и iOS.

Vyas Reddy 10.09.2019 21:11

Я сделал функциональный эквивалент с хуками состояний на основе версии Damien Buchet. Страница капчи такая же. Собственный модуль React:

import React, {useState} from 'react'
import {Text, View, TextInput, Button,StyleSheet, KeyboardAvoidingView} from 'react-native'
import { WebView } from 'react-native-webview';
import firebase from '../../components/utils/firebase'  /contains firebase initiation


const captchaUrl = 'https://my-domain.web.app/captcha-page.html';

const LoginScreenPhone = props => {
const [phoneNumber, setPhoneNumber] = useState();
const [step, setStep] = useState('initial');
const [smsCode, setSmsCode] = useState();
const [verificationId, setVerificationId]=useState();

const onAuthStateChanged = async user => {
    if (user) {
        const token = await firebase.auth().currentUser.getIdToken();
        if (token) {
            // User is fully logged in, with JWT in token variable
        }
    }
}

firebase.auth().onAuthStateChanged(onAuthStateChanged);



const onGetMessage = async event => {

    const message = event.nativeEvent.data;
    console.info(message);
    switch (message) {
        case "DOMLoaded":

            return;
        case "ErrorSmsCode":
            // SMS Not sent or Captcha verification failed. You can do whatever you want here
            return;
        case "":
            return;
        default: {
            setStep('promptSmsCode');
            setVerificationId(message);
            }
        }
}


const onSignIn = async () => {
    setStep('smsCodeSubmitted');
    const credential = firebase.auth.PhoneAuthProvider.credential(verificationId, smsCode);
    firebase.auth().signInWithCredential(credential);
    props.navigation.navigate('Home');
}

return (
    <View>
    {step==='initial' && (
        <KeyboardAvoidingView  behavior = "padding" enabled>
            <TextInput
                label='Phone Number'
                value = {phoneNumber}
                onChangeText = {phone =>setPhoneNumber(phone)}
                mode = "outlined"
            />
            <Button mode = "contained" onPress = {()=>setStep('phoneSubmitted')} title=' Send me the code!'>

            </Button>
        </KeyboardAvoidingView >
    )}

  {step==='phoneSubmitted' && (
        <View style = {{flex:1, minHeight:800}}>
            <Text>{`getToken('${phoneNumber}')`}</Text>
        <WebView
         injectedJavaScript = {`getToken('${phoneNumber}')`}          
            source = {{ uri: captchaUrl }}
            onMessage = {onGetMessage}
        />
        </View>
    )}

   {step==='promptSmsCode' && (<KeyboardAvoidingView behavior = "padding" enabled>
            <TextInput
                label='Verification code'
                value = {smsCode}
                onChangeText = {(sms)=>setSmsCode(sms)}
                mode = "outlined"
                keyboardType='numeric'
            />
            <Button mode = "contained" onPress = {onSignIn} title='Send'>

            </Button>
    </KeyboardAvoidingView >)}
    </View>
);
}


export default LoginScreenPhone;

Швейцар обеспечивает поддержку аутентификации телефона Firebase для приложений Expo без отсоединения. Он также поставляется с настраиваемыми компонентами пользовательского интерфейса для Expo / React Native.

Ссылка: https://doorman.cool

Пример кода выглядит примерно так:

export default withPhoneAuth(App, {
  doorman: {
    publicProjectId: "ID here"
  }
})

Другие вопросы по теме