You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Actions SDK云函数使用与用户UID获取及认证问题咨询

Hey there! Let's break down your questions step by step since you're new to the Actions SDK. I'll cover UID retrieval, calling your getUser function, user creation, authentication flows, and how to handle auth after triggering the main intent.

解答你的Actions SDK用户认证与UID获取问题

一、UID是什么?怎么正确获取并调用getUser?

First off, the UID you're looking for is the unique ID tied to the user's Google account, which the Actions SDK provides directly via conv.user.id in your conversation handler. Your current getUser function is set up as a standalone HTTP function expecting a URL parameter (req.params.uid), which won't work for Assistant requests—we need to refactor it to integrate with your Actions flow.

Step 1: Initialize Firebase Admin (you missed this!)

First, add this line right after importing admin to connect your function to Firebase:

admin.initializeApp(); // 放在文件顶部,functions和admin引入之后

Step 2: Refactor getUser into a reusable helper function

Instead of a separate HTTP endpoint, make it an async function that accepts a UID and fetches from Firestore:

// Helper function to fetch user data from Firestore
async function getUser(uid) {
  try {
    const userDoc = admin.firestore().doc(`users/${uid}`);
    const snapshot = await userDoc.get();
    return snapshot.exists ? snapshot.data() : null;
  } catch (error) {
    console.error('Failed to fetch user:', error);
    throw error;
  }
}

Step 3: Call getUser from your main intent

Now you can use this helper directly in your dairyProduct function's MAIN intent:

app.intent('actions.intent.MAIN', async (conv, input) => {
  // Grab the user's Google-assigned UID
  const userUid = conv.user.id;
  console.log('Current user UID:', userUid);

  try {
    const userData = await getUser(userUid);
    if (userData) {
      conv.ask(`<speak>Hi! Welcome back, ${userData.name}! You said <say-as>${input}</say-as>.</speak>`);
    } else {
      // User doesn't exist yet—prompt them to create an account
      conv.ask(`<speak>Hi there! Looks like you're new here. You said <say-as>${input}</say-as>. What's your name? I'll set up your account.</speak>`);
      // Set a context to handle the account creation flow next
      conv.contexts.set('create_user', 5);
    }
  } catch (error) {
    conv.ask('<speak>Oops, something went wrong fetching your info. Try again later!</speak>');
  }
});

二、User Creation & End-User Authentication Examples

1. Creating a User Profile (Firestore)

When a new user joins, collect their details (like name) and save to Firestore with their UID as the document ID:

// Add an intent to handle account creation
app.intent('create_user_intent', async (conv, userName) => {
  const userUid = conv.user.id;

  try {
    await admin.firestore().doc(`users/${userUid}`).set({
      name: userName,
      createdAt: admin.firestore.FieldValue.serverTimestamp()
    });
    conv.close(`<speak>All set! Welcome aboard, ${userName}!</speak>`);
  } catch (error) {
    conv.ask('<speak>Sorry, I couldn\'t create your account right now. Try again later?</speak>');
  }
});

2. Google Account OAuth2 Authentication

If you need access to more user data (like email or full name), set up Google Sign-In for account linking:

Step 1: Configure Account Linking in Actions Console

  • Go to your Actions project → Account Linking
  • Select Google Sign-In as the auth method
  • Choose scopes like profile and email to request the data you need
  • Save your settings

Step 2: Handle Authentication in Code

Update your MAIN intent to check for auth, and add a handler for the sign-in result:

// Import the SignIn class first
const {actionssdk, SignIn} = require('actions-on-google');

// MAIN intent with auth check
app.intent('actions.intent.MAIN', async (conv) => {
  // Check if the user is authenticated
  if (!conv.user.profile) {
    // Prompt the user to sign in
    conv.ask(new SignIn());
  } else {
    // User is authenticated—get their profile data
    const userProfile = conv.user.profile;
    const userUid = conv.user.id;
    console.log('User profile:', userProfile);

    // Create or update the user in Firestore
    const userData = await getUser(userUid);
    if (!userData) {
      await admin.firestore().doc(`users/${userUid}`).set({
        name: userProfile.displayName,
        email: userProfile.email,
        createdAt: admin.firestore.FieldValue.serverTimestamp()
      });
    }

    conv.ask(`<speak>Hi ${userProfile.displayName}! Great to see you again!</speak>`);
  }
});

// Handle the sign-in result
app.intent('actions.intent.SIGN_IN', async (conv, input, signIn) => {
  if (signIn.status === 'OK') {
    // Auth succeeded—fetch the user's profile
    const userProfile = conv.user.profile;
    const userUid = conv.user.id;

    // Update Firestore with latest info
    await admin.firestore().doc(`users/${userUid}`).set({
      name: userProfile.displayName,
      email: userProfile.email,
      lastLogin: admin.firestore.FieldValue.serverTimestamp()
    }, { merge: true });

    conv.ask(`<speak>Sign-in successful! Welcome, ${userProfile.displayName}!</speak>`);
  } else {
    conv.ask('<speak>You didn\'t complete sign-in, so I can\'t access your account details right now.</speak>');
  }
});

三、Authentication Flow After Triggering the MAIN Intent

When a user says "Talk to Dairy Product" to trigger your main intent, here's what happens:

  1. Your code checks if the user is authenticated via conv.user.profile
  2. If not authenticated, the SignIn prompt is sent to the user—Google Assistant will walk them through logging into their Google account
  3. Once signed in, the actions.intent.SIGN_IN intent is triggered, where you handle the success/failure
  4. On success, you can create/update the user's Firestore document using their UID and profile data
  5. From then on, you can always use conv.user.id to fetch their data with your getUser helper

四、Update Your action.json

Add the actions.intent.SIGN_IN intent to your inDialogIntents so Assistant knows to route sign-in requests to your fulfillment:

{
  "actions": [
    {
      "description": "Default Welcome Intent",
      "name": "MAIN",
      "fulfillment": {
        "conversationName": "testapp"
      },
      "intent": {
        "name": "actions.intent.MAIN",
        "trigger": {
          "queryPatterns": [
            "Talk to Dairy Product"
          ]
        }
      }
    }
  ],
  "conversations": {
    "testapp": {
      "name": "testapp",
      "url": "https://us-central1-samplejs6-id.cloudfunctions.net/dairyProduct",
      "fulfillmentApiVersion": 2,
      "inDialogIntents": [
        {
          "name": "actions.intent.CANCEL"
        },
        {
          "name": "actions.intent.SIGN_IN"
        }
      ]
    }
  },
  "locale": "en"
}

内容的提问来源于stack exchange,提问作者Thirumani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:17:10