Flutter调用Firebase云函数admin.auth.updateUser

3

编辑**

好的,我已经成功通过第一个答案提供的参数来使我的函数工作,但现在我遇到了一个问题,我的函数正在Firebase中创建一个全新的用户而不是更新一个现有的用户,我传递给auth.admin.updateUser的uid是要更新电子邮件的现有用户的uid。这是更新后的云函数,它正在添加新用户而不是更新现有用户:

    exports.updateEmail = functions.https.onCall((data, context) => {

  const email = data.email;
  const uid = data.uid;

  admin.auth().updateUser(uid, {
              email: email
          })
          .then(function(userRecord) {
              // See the UserRecord reference doc for the contents of userRecord.
              console.log("Successfully updated user", userRecord.toJSON());
              return response.status(200).json(userRecord.toJSON());
          })
          .catch(function(error) {
              console.log("Error updating user:", error);
              return response.status(404).json({
                  error: 'Something went wrong.'
              });
          });
});

我从Firebase文档中得到了该函数,但它没有按照我预期的方式工作。

原帖:

当我从我的Flutter代码中调用云函数时,我遇到了一些困难。我的问题是uid和email字段未定义,尽管我正在使用busboy字段将它们传递给云函数。

我试图像下面这样将email和uid字段传递给函数:

final request = http.MultipartRequest('POST', Uri.parse('****************my function url************'));

request.fields['email'] = Uri.encodeComponent(newEmail);
request.fields['uid'] = Uri.encodeComponent(selectedUser.uid);

request.headers['Authorization'] = 'Bearer ${_authenticatedUser.token}';

  final http.StreamedResponse streamedResponse = await request.send();

在 Node.js 端,我正在尝试使用 busboy 来使用这些字段,以下是我的 Node.js 云函数:

exports.changeEmail = functions.https.onRequest((request, response) => {

if (!request.headers.authorization ||
    !request.headers.authorization.startsWith('Bearer ')
) {
    return response.status(401).json({
        error: 'Unauthorized.'
    });
}

let idToken;
idToken = request.headers.authorization.split('Bearer ')[1];
let email;
let uid;

const busboy = new Busboy({
    headers: request.headers
});

busboy.on('field', (fieldname, value) => {

    if (fieldname == 'email') {


        email = decodeURIComponent(value);
    }

    if (fieldname == 'uid') {

        uid = decodeURIComponent(value);
    }
});



admin.auth().updateUser(uid, {
        email: email
    })
    .then(function(userRecord) {
        // See the UserRecord reference doc for the contents of userRecord.
        console.log("Successfully updated user", userRecord.toJSON());
        return response.status(200).json(userRecord.toJSON());
    })
    .catch(function(error) {
        console.log("Error updating user:", error);
        return response.status(404).json({
            error: 'Something went wrong.'
        });
    });

即使我使用 busboy fields 传递了字段,但它们无法在函数中设置,这里有什么我做错了吗?

}

1个回答

0

为什么不使用可调用函数?它会自动接收身份验证数据。

文档甚至有关于如何获取uid和电子邮件的示例:

声明该函数:

exports.addMessage = functions.https.onCall((data, context) => {
  // ...
});

从上下文参数中获取用户属性:

// Message text passed from the client.
const text = data.text;
// Authentication / user information is automatically added to the request.
const uid = context.auth.uid;
const name = context.auth.token.name || null;
const picture = context.auth.token.picture || null;
const email = context.auth.token.email || null;

在你的Flutter代码中调用该函数:

安装cloud_functions包,然后:

import 'package:cloud_functions/cloud_functions.dart';

await CloudFunctions.instance.call(functionName: 'addMessage');

如果在调用函数之前用户已通过身份验证,那么你所需要做的就是这些。
你也可以给函数传递额外的参数:
await CloudFunctions.instance.call(functionName: 'addMessage', parameters: {"email": "whatever@example.com"});

任何参数都将传递到函数端的数据参数。

非常感谢,一切都完美解决了!在云函数包中,iOS 设置区域时出现了一些小问题,但是在修复后,我已成功作为管理员更新了用户的电子邮件!我给你点了赞,但我的声望还不够高,无法显示! - Callum Clift
然而,我现在遇到了一个问题,我的函数本身存在问题。我想要更新现有用户的电子邮件地址,但似乎它正在添加一个全新的用户。 - Callum Clift
admin.auth().updateUser(uid, { email: email }) .then(function(userRecord) { // 请参阅 UserRecord 参考文档以了解 userRecord 的内容。 console.log("用户更新成功", userRecord.toJSON()); return response.status(200).json(userRecord.toJSON()); }) .catch(function(error) { console.log("更新用户时出错:", error); return response.status(404).json({ error: '出现错误。' }); }); - Callum Clift
太好了,它起作用了!但它是否正在创建一个具有不同uid的新用户?也许如果您创建一个新问题并提供详细信息,人们就可以更容易地帮助您。 - Ricardo Smania
@RicardoSmania 我看到你可以将键值对作为parameters: {"email": "whatever@example.com"}传递,所以在函数内部它会作为data.email存在还是需要将data进行JSON解码然后从中获取email参数? - Vincenzo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接