aws-amplify / aws-amplify/amplify-ui
FaceLivenessDetector keeps loading without move to oval-shaped screen
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.1k
- Forks
- 347
- Avg merge
- 18h 29m
- Merged PRs (30d)
- 9
Description
Before creating a new issue, please confirm:
- I have searched for duplicate or closed issues and discussions.
- I have tried disabling all browser extensions or using a different browser
- I have tried deleting the node_modules folder and reinstalling my dependencies
- I have read the guide for submitting bug reports.
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
The app is stuck here, it should go to the oval-shaped page
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the React FaceLiveness component and its FaceLivenessDetector entry point, then reproduce the behavior with WebViewController in a minimal Flutter project using Safari. Confirm the component moves from the loading state to the oval-shaped verification screen inside a mobile webview, and use the reported reproduction code and screenshot as the baseline.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- flutter, react, typescript
- Domain
- frontend, mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100