hidglobal / digitalpersona-devices

DigitalPersona Security Devices support library
https://hidglobal.github.io/digitalpersona-devices/index.html
MIT License
64 stars 41 forks source link

TypeError: FingerprintReader is not a constructor #57

Closed juanpuertas closed 6 months ago

juanpuertas commented 7 months ago
import React, { useEffect, useState } from 'react';
import Head from 'next/head';
import dynamic from 'next/dynamic';

import { Box, Button, Grid, TextField, Typography } from '@mui/material';
// Dynamically import FingerprintReader with SSR turned off
const FingerprintReader = dynamic(
    () => import('@digitalpersona/devices').then((mod) => mod.FingerprintReader),
    { ssr: false } // This disables server-side rendering for this module
  );

  const index = () => {
    const [reader, setReader] = useState(null);

    // Initialize the reader once the component has mounted
    useEffect(() => {
        setReader(new FingerprintReader());
    }, []);

    const handleButtonClick = async () => { 
        console.log(reader)
    };

I modified in '@digitalpersona/devices/dist/es5.bundles/index.umd.js' Is the import this for the WebSdk in reactjs with nextjs typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@digitalpersona/core'), require('../../../../../public/modules/websdk')) : and with this I had no more problems with the import of the WebSdk and in my code I set the import FingerprintReader to have SSR disabled so that it runs on the browser side but I get this error 'FingerprintReader is not a constructor', what could be causing this?

a-bronx commented 7 months ago

I'm not familiar with NextJS, sorry. Try to debug and inspect what is in the mod the import returns to you. I'd try:

const devices = dynamic(
    () => import('@digitalpersona/devices'),
    { ssr: false } // This disables server-side rendering for this module
);
...
useEffect(() => {
    setReader(new devices.FingerprintReader());
}, []);
juanpuertas commented 7 months ago

The same error keeps appearing, I tried the way you mentioned and it still doesn't work, I will keep trying if I manage to do it I will mention it, thank you very much anyway and if anyone else knows how to solve this I would appreciate it :)

juanpuertas commented 7 months ago
import React, { useEffect, useState } from 'react';
import Head from 'next/head';
import dynamic from 'next/dynamic';

/* import { FingerprintReader, QualityCode, ErrorOccurred, SampleFormat } from '@digitalpersona/devices'; */
import { Box, Button, Grid, TextField, Typography } from '@mui/material';
// Dynamically import FingerprintReader with SSR turned off
const FingerprintReader = dynamic(
    () => import('@digitalpersona/devices').then((mod) => mod.FingerprintReader),
    { ssr: false } // This disables server-side rendering for this module
  );

  const index = () => {
    const [reader, setReader] = useState(null);
    const [nombres, setNombres] = useState('');
    const [correo, setCorreo] = useState('');
    const [password, setPassword] = useState('');
    const [fingerprint, setFingerprint] = useState(null);

    // Initialize the reader once the component has mounted
    useEffect(() => {
        setReader(FingerprintReader);
    }, []);

    const handleButtonClick = async () => { 
        console.log(reader)
    };
    return (
        <>
            <Box height='100vh' display='flex' justifyContent='center' alignItems='center'>
                <Box width='50%'>
                    <Typography variant='h1' textAlign='center'> Registro de usuario con Biometrico </Typography>
                    <Grid container justifyContent='center' mt={2}>
                        <Grid item xs={12} mt={2} display='center' justifyContent='center'>
                            <TextField
                                variant='outlined'
                                onChange={(e)=> setNombres(e.target.value)}
                                label='Nombres'
                            />
                        </Grid>

By doing it this way in the set Reader(Fingerprint Reader); I didn't get the error mentioned above and when I did the console.log in the onClick function I got this value, and could you guide me in this case?

image

a-bronx commented 7 months ago

It looks like the dynamic() tries to convert the library into a React component, with render etc. Try a vanilla JS async import, without dynamic.

juanpuertas commented 6 months ago

I have problems again with the WebSdk, I was thinking of doing the project first with html and vanilla javascript, could you tell me from the library which files are necessary to be able to save and read a fingerprint, to be able to carry out authentication processes. Likewise, I will not leave aside the nextjs project, I will only not give it priority for the moment, I also wanted to mention that with this code I imported both the FingerprintReader and the WebSdk only from the browser side, but it still gives me this common error

const index = () => {
    const [nombres, setNombres] = useState('');
    const [correo, setCorreo] = useState('');
    const [password, setPassword] = useState('');
    const [fingerprint, setFingerprint] = useState(null);
    let reader;
    let FingerprintReader;
    useEffect(() => {
        if (typeof window !== 'undefined') {
            FingerprintReader = require('@digitalpersona/devices').FingerprintReader;
            let WebSdk = require('../modules/WebSdk');
            reader = new FingerprintReader();
        }
    }, []);
omarasael1980 commented 6 months ago

I implemented the reading of the fingerprint, the part of saving the fingerprint and making the comparison is still missing, but it seems to me that it is not done with this library "@digitalpersona/devices" but if you have information about it I will appreciate it. On the other hand, I have an older system made in C# that does the enrollment but uses another library, we have a very large database, the interest lies in the new implementation in React being able to read the fingerprint and pass it to a webservice to do the comparison, but so far I have not been successful, because the base64 that are produced in both systems are very different.

a-bronx commented 6 months ago

which files are necessary to be able to save and read a fingerprint, to be able to carry out authentication processes.

I believe this is answered in the F.A.Q.

with this code I imported both the FingerprintReader and the WebSdk

Did you try to debug your code and inspect your variables, as I suggested? What objects do you see in FingerprintReader and WebSdk variables after loading?

juanpuertas commented 6 months ago

Hello again @a-bronx I already managed to solve my problem with the library imports, especially using the example shown by colleague @omarasael1980 in which he made a wonderful example of the implementation of the library with reactjs, especially because he shows it in his project, which is why he project that I had in progress, I will continue doing it with reactjs, you can close the case and I highly recommend @omarasael1980's project for future library implementation questions in react. I just want to ask one last question. I had read that for the comparison of fingerprints with @digitalpersona is it necessary to make any additional payment with any webservices? Since I think I have read previously that this needs to be done outside the browser for security and performance reasons, is this true? Thanks again for their time to @a-bronx and @omarasael1980 for example

a-bronx commented 6 months ago

@juanpuertas yes, the library does not do fingerprint matching, and for this you'll need a server with a fingerprint matching engine.