0

I am trying to access the auth.id for the user making this call. context.auth is undefined when I use onCall to define a callable function and invoke it from my app using httpsCallable while a user is signed in with Firebase Authentication.

const { onCall } = require('firebase-functions/v2/https');
const { error } = require('firebase-functions/logger');
import * as Postmark from 'postmark';
import { v4 as uuidv4 } from 'uuid';
import admin = require('firebase-admin');
import { FieldValue } from 'firebase-admin/firestore';
import * as functions from 'firebase-functions';
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
import * as dotenv from 'dotenv';
dotenv.config();

admin.initializeApp();

...

exports.createVerificationSession = onCall(async (data: any, context: any) => {
  console.log('context');
  console.log(context);
  console.log('Creating verification session');
  if (!context.auth) {
    console.log('No authentication context available.');
    throw new functions.https.HttpsError(
      'unauthenticated',
      'The function must be called while authenticated.',
    );
  }
  try {
    const verificationSession =
      await stripe.identity.verificationSessions.create({
        type: 'document',
        metadata: {
          user_id: context.auth.uid,
        },
      });
    const clientSecret = verificationSession.client_secret;
    console.log('Client secret:', clientSecret);
    return { clientSecret };
  } catch (error) {
    console.error('Error creating verification session:', error);
    throw new functions.https.HttpsError(
      'internal',
      'Unable to create verification session.',
    );
  }
});

Here's my FE code:

function Payment() {
  const [clientSecret, setClientSecret] = useState('');

  const fetchClientSecret = async () => {
    console.log('Fetching client secret');
    const functions = getFunctions();
    const createVerificationSession = httpsCallable(
      functions,
      'createVerificationSession',
    );

    try {
      console.log('Calling createVerificationSession');
      await createVerificationSession().then((result) => {
        console.log('Result:', result);
      });
      // setClientSecret(response.data.clientSecret);
    } catch (error) {
      console.error('Failed to fetch client secret:', error);
      // Handle errors here appropriately
    }
  };

  useEffect(() => {
    fetchClientSecret();
  }, []);

  // Ensure stripePromise and clientSecret are loaded before rendering the Elements provider
  if (!stripePromise || !clientSecret) {
    return <p>Loading payment details...</p>;
  }

  const options = {
    clientSecret: clientSecret,
  };

  return (
    <Elements stripe={stripePromise} options={options}>
      <CheckoutForm />
    </Elements>
  );
}

Could I pass it through from there? The auth.uid or something?

0

1 Answer 1

1

You haven't defined your callable function correctly. The trigger callback doesn't receive (data: any, context: any). Take a look at the example in the documentation - be sure to use v2 examples and not v1. A callable receives one argument of type CallableRequest. If you're looking for the authenticated user's ID, you can find that in the auth property:

exports.createVerificationSession = onCall(async (request) => {

  // Examples from the documentation
  // Authentication / user information is automatically added to the request.
  const uid = request.auth.uid;
  const name = request.auth.token.name || null;
  const picture = request.auth.token.picture || null;
  const email = request.auth.token.email || null;

  ...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.