amplify-ui icon indicating copy to clipboard operation
amplify-ui copied to clipboard

FaceLivenessDetector keeps loading without move to oval-shaped screen

Open Linkadi98 opened this issue 1 year ago • 2 comments

Before creating a new issue, please confirm:

On which framework/platform are you having an issue?

Flutter

Which UI component?

Liveness

How is your app built?

React App

What browsers are you seeing the problem on?

Safari

Which region are you seeing the problem in?

ap-northeast-1

Please describe your bug.

I have tried to run the FaceLivenessDetector on the web browser sucessfully without any problems. But when I try to open the web app from one of the following Flutter webview plugins (WebViewFlutter, InAppWebView, InAppBrowser from InAppWebView), the app always keeps loading after I get the sessionId from my custom backend. It should go the the oval-shaped page to verify my face. But if I use the url_launcher package to directly open Safari browser, it works like the web browser. The issue just happens when I try to show the app in a mobile webview.

What's the expected behaviour?

Mobile webview should work as same as web browser on desktop

Help us reproduce the bug!

Create a new flutter project and add the WebViewFlutter package from pub.dev Paste the code below to run the webview

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class FaceLivenessWebViewFlutter extends StatefulWidget {
  const FaceLivenessWebViewFlutter({super.key});

  @override
  State<FaceLivenessWebViewFlutter> createState() =>
      _FaceLivenessWebViewFlutterState();
}

class _FaceLivenessWebViewFlutterState
    extends State<FaceLivenessWebViewFlutter> {
  late WebViewController _webViewController;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    _webViewController = WebViewController()
      ..loadRequest(Uri.parse('[Place an url points to the react app, can be a ngrok url]'))
      ..setJavaScriptMode(JavaScriptMode.unrestricted);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Face Liveness'),
        actions: [],
      ),
      body: Column(
        children: [
          Expanded(
            child: WebViewWidget(
              controller: _webViewController,
            ),
          ),
        ],
      ),
    );
  }
}

Code Snippet

import React, {useEffect, useState} from "react";
import {Button, Heading, Loader, View} from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import {FaceLivenessDetector} from '@aws-amplify/ui-react-liveness';

interface FaceLivenessProps {
    faceLivenessAnalysis: (data: any) => void;
}

const FaceLiveness: React.FC<FaceLivenessProps> = ({faceLivenessAnalysis}) => {
    const [loading, setLoading] = useState(true);
    const [sessionId, setSessionId] = useState<string | null>(null);

    const endpoint = process.env.REACT_APP_ENV_API_URL || '';

    const fetchCreateLiveness = async () => {
        try {
            const response = await fetch(`${endpoint}/create_session`);
            const data = await response.json();
            console.log(JSON.stringify(data));
            setSessionId(data.sessionId);
            setLoading(false);
        } catch (error) {
            console.error("Failed to create liveness session", error);
        }
    };

    useEffect(() => {
        fetchCreateLiveness();
    }, [endpoint]);

    const handleAnalysisComplete = async () => {
        try {
            const response = await fetch(`${endpoint}/check?sessionId=${sessionId}`, {
                method: 'GET',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                }
            });
            const data = await response.json();
            faceLivenessAnalysis(data.body);
        } catch (error) {
            console.error("Failed to get liveness session result", error);
        }
    };

    const handleRetry = () => {
        setLoading(true);
        fetchCreateLiveness();
    };

    return (
        <>
            {loading ? (
                <Loader/>
            ) : (
                <FaceLivenessDetector
                    sessionId={sessionId || ''}
                    region={process.env.REACT_APP_REGION || ''}
                    disableStartScreen={true}
                    onAnalysisComplete={handleAnalysisComplete}
                    components={{
                        PhotosensitiveWarning: () => null,
                        ErrorView: ({}) => (
                            <View className="container">
                                <Heading level={6} className="heading">Chưa nhận diện được khuôn mặt</Heading>
                                <div style={{marginBottom: '20px'}}></div>
                                <Button className="button" onClick={handleRetry}>Thử lại</Button>
                            </View>
                        )
                    }}
                    onError={(error) => {
                        console.error(error);
                    }}
                />
            )}
        </>
    );
}

export default FaceLiveness;

Console log output

Nothing shows up

Additional information and screenshots

IMG_0E1D321B72CC-1 The app is stuck here, it should go to the oval-shaped page

Linkadi98 avatar Nov 18 '24 06:11 Linkadi98

Hello, @Linkadi98 and thanks for opening this issue. Flutter isn't supported at this point for the Face Liveness component, both directly and via the webview integrations. We'll mark this as a feature request to further review it internally and reach back out with any additional questions or updates we have.

cwomack avatar Nov 19 '24 00:11 cwomack