这是一个真正的抓头人。我有一个使用https.onCall()的云函数。此功能调用是从 Android应用程序上的受密码保护的区域触发的(我将 Firestore 用作服务器)。为了访问此区域,我强迫用户重新输入密码,然后调用FirebaseAuth.getInstance()。getCurrentUser()。reauthenticate()。
我已经运行了无需重新认证就调用https.onCall()云函数的代码,并且该函数保留了用户的认证凭据,因此在重新认证时,将其范围缩小了。我想念什么吗?我需要做些什么来通知身份验证更新的云功能吗?
我在功能日志中收到的错误消息是: “ TypeError:无法读取未识别对象的属性'uid'”。具体来说,这是在我尝试通过以下方法获取经过身份验证的用户的uid时发生的:
id
假设是因为我没有得到上述错误,是因为没有通过上下文传入的经过身份验证的数据。
为了更好地说明正在发生的事情,这是我的流程/过程:
用户从选项菜单中选择“帐户”。这将启动一个dialogFragment,要求输入用户密码:
dialogFragment中的按钮代码:
const adminUID = context.auth.uid;
在选择loginButton并输入用户的密码后,我们会将数据传递给重新验证方法:
重新验证代码:
loginButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view) {
//execute the loginReAuth method
authenticateSession.loginAdminReAuth(adminEmailAddress, passwordField);
}
});
重新认证成功后,我们将运行意图并将其带到AccountSettingsActivity。在此活动中,我具有方法:deleteAccount(),该方法由buttonDialog中的buttonClick触发,以确认操作。
以下是触发该方法的buttonClick:
public void loginAdminReAuth(final String email, TextView passwordText) {
user = FirebaseAuth.getInstance().getCurrentUser();
String password = passwordText.getText().toString();
AuthCredential credential = EmailAuthProvider.getCredential(email, password);
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Intent intent = new Intent(context, AccountSettingsActivity.class);
context.startActivity(intent);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "re-authenticate:failure", task.getException());
Toast.makeText(MyApplication.getContext(), task.getException().getMessage(),
Toast.LENGTH_SHORT).show();
}
}
});
}
这是发出云功能请求的deleteAccount()方法:
调用云函数的方法:
@Override
public void onDialogOKPressed(DialogFragment dialog) {
dialog.dismiss();
if (buttonSelected.equals("accountUpdateButton")) {
//update code here.
}
else if (buttonSelected.equals("accountDeleteButton")) {
deleteAccount(admin);
}
}
最后,这是执行请求的Cloud Firestore代码。 云函数https.onCall():
private Task<String> deleteAccount(Admin selectedAdmin) {
Gson gson = new Gson();
String selectedAdminJson;
selectedAdminJson = gson.toJson(selectedAdmin);
Map<String, Object> data = new HashMap<>();
data.put("selectedAdminJson", selectedAdminJson);
return mFunctions
.getHttpsCallable("deleteAccount")
.call(data)
.continueWith(new Continuation<HttpsCallableResult, String>() {
@Override
public String then(@NonNull Task<HttpsCallableResult> task) throws Exception {
// This continuation runs on either success or failure, but if the task
// has failed then getResult() will throw an Exception which will be
// propagated down.
Log.d(TAG, "results from deleteAccount: " + task.getResult().getData().toString());
String result = (String) task.getResult().getData();
return result;
}
});
}
再一张。这是我的index.ts:
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
import * as functions from 'firebase-functions';
// The Firebase Admin SDK to access the Firebase Realtime Database.
import * as admin from 'firebase-admin'
export = module.exports = functions.https
.onCall(async (data, context) => {
//selectedAdminJson received from app client and converted to admin object class
const selectedAdminJson = data.selectedAdminJson;
const adminUID = context.auth.uid;
//Error checking
// Checking attribute.
if (!(typeof selectedAdminJson === 'string') || selectedAdminJson.length === 0) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('invalid-argument', 'The function must be called with ' +
'one arguments "JSON object" containing selectedAdmin to add.');
}
// Checking that the user is authenticated OR if the calling adminID doesn't match the data received
if (!context.auth) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
'while authenticated.');
}
try {
//METHODS EXECUTED HERE
} catch (error) {
console.error("Error removing adminUserGroup data: ", error);
}
// Returning result to the client.
return {
selectedAdminJson: "selectedAdminJson received and processing."
};
});
答案 0 :(得分:0)
好的,所以我认为我解决了这个问题。看来问题是我在httpsCallable()可以完全发送身份验证信息之前注销了用户。
我正在做以下事情:
deleteAccount(firebaseLocalCache.thisAdminFromCache());
session.logoutUser();
相反,在deleteTask()方法返回Task对象之后,我可能不得不做某种继续。这样,只有从服务器获得响应后,我们才注销用户。