我正试图从我的应用程序中调用一个firebase云函数。我正在使用xamarin安卓系统。我试着用来称呼它
public Task<string> AddPoint()
{
FirebaseFunctions firebaseFunctions =
FirebaseFunctions.GetInstance(app));
var func = firebaseFunctions.GetHttpsCallable("addPoint").Call(someData);
return func.Result.Cast<Task<string>>();
}
但是firebase控制台没有注册该函数被调用。返回函数。Result.Cast>((抛出一个错误:"Java.Lang.IollegalStateException:任务尚未完成。"添加断点后,它在Result属性中显示相同的内容。func属性(IsCanceled、Iscompleted和IsSuccessful(始终为false。我在中遵循了示例代码https://firebase.google.com/docs/functions/callable,但它不包括c#示例。
我想明白了。首先,需要实现IContinution和IOScessListener接口:
public class Continuation : Java.Lang.Object, Android.Gms.Tasks.IContinuation
{
public Java.Lang.Object Then(Android.Gms.Tasks.Task task)
{
return task.Result;
}
}
public class TaskSuccessListener : Java.Lang.Object, IOnSuccessListener
{
public event EventHandler<OnSuccessEventArgs> Success;
public void OnSuccess(Java.Lang.Object result)
{
Success?.Invoke(this, new OnSuccessEventArgs { Result = result });
}
public class OnSuccessEventArgs : EventArgs
{
public Java.Lang.Object Result { get; set; }
}
}
一个可调用的云函数的响应是Java.Lang.Object,它可以被转换成HashMap。然而,func是一个java任务,它不会阻塞.Net任务线程。因此,有必要使用TaskCompletionSource手动暂停线程。当云函数成功返回时,将调用IOnScessListener。然后可以设置TaskCompletionSource以继续执行任务。它可以这样使用:
public class FirebaseFunction : AppCompatActivity
TaskCompletionSource<bool> isRunning;
TaskSuccessListener.Success += TaskSuccessListener_Success;
public async Task<string> AddPoint()
{
FirebaseFunctions firebaseFunctions =
FirebaseFunctions.GetInstance(FirebaseApp));
var func = firebaseFunctions.GetHttpsCallable("function")
.Call(someData)
.ContinueWith(new Continuation())
.AddOnSuccessListener(this, taskCompletionListener);
await isRunning.Task;
HttpsCallableResult httpsResult = (HttpsCallableResult)func.Result;
HashMap map = httpsResult.Data.JavaCast<HashMap>();
if (map.ContainsKey("data"))
{
response = map.Get("data").ToString();
}
return response;
}
private void TaskSuccessListener_Success(object sender, TaskSuccessListener.OnSuccessEventArgs e)
{
//Alternatively it is possible to get the result directely from e.result
//HttpsCallableResult httpsResult = (HttpsCallableResult)e.Result;
//HashMap map = httpsResult.Data.JavaCast<HashMap>();
isRunning.SetResult(true);
}
}
我找到了另一个基于您的解决方案,它对我有效,看起来更简单:
var func = FirebaseFunctions.Instance.GetHttpsCallable("sayHello").Call();
await func;
HttpsCallableResult httpsResult = (HttpsCallableResult)func.Result;