Sign a samlResponse using javascript without node.js

I’m working on a SAMLResponse generator in JavaScript without using server-side solutions.
The response is generated, but the signing process seems to fail, as I get the following error:
XMLJS0013: Cryptographic error: Invalid digest for URI '#_n1rwnf4r2'. Calculated digest is * but the xml to validate supplies digest *
I’m using the following libraries to handle the signature and digest:
jsrsasign.js
forge.js
Here is the part of my code responsible for signing the response:

const canonicalizedAssertion = canonicalize(assertion);
const digestValue = generateDigestValue(canonicalizedAssertion);

let signedInfo = `
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
    <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
    <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
    <Reference URI="#_${assertionID}">
        <Transforms>
            <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
        <DigestValue>${digestValue}</DigestValue>
    </Reference>
</SignedInfo>`;

const canonicalizedSignedInfo = canonicalize(signedInfo);
const signatureValue = generateSignature(canonicalizedSignedInfo);

That will added to the signature:

let signedAssertion = assertion.replace('</saml2:Assertion>', `
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        ${signedInfo}
        <SignatureValue>${signatureValue}</SignatureValue>
        <KeyInfo>
            <X509Data>
                <X509Certificate>${certificateStr.replace(/-----BEGIN CERTIFICATE-----/g, "")
            .replace(/-----END CERTIFICATE-----/g, "")
            .replace(/n/g, "")}</X509Certificate>
            </X509Data>
        </KeyInfo>
    </Signature>
</saml2:Assertion>`);

Here’s how I canonicalize the XML and generate the digest:

function canonicalize(xmlString) {
    return xmlString.replace(/ss+/g, ' ').trim();
}

function generateDigestValue(content) {
    const sha256 = forge.md.sha256.create();
    sha256.update(content, 'utf8');
    return forge.util.encode64(sha256.digest().bytes());
}

Does anyone have experience with this issue? How can I ensure the digest matches correctly? Any help would be appreciated!