Невозможно вызвать облачную функцию firebase из xamarin android - PullRequest
0 голосов
/ 03 марта 2020

Я пытаюсь вызвать облачную функцию firebase из моего приложения. Я использую xamarin android. Я пытаюсь вызвать его с помощью:

public Task<string> AddPoint()
    {
        FirebaseFunctions firebaseFunctions = 
        FirebaseFunctions.GetInstance(app));

        var func = firebaseFunctions.GetHttpsCallable("addPoint").Call(someData);

        return func.Result.Cast<Task<string>>();
    }

Но консоль Firebase не регистрирует, что функция была вызвана. Функция возврата fun c .Result.Cast> () выдает ошибку: «Java .Lang.IllegalStateException: задача еще не завершена». Добавляя точку останова, он говорит то же самое в свойстве Result. fun c свойства (IsCanceled, Iscompleted и IsSuccessful) всегда ложны. Я следовал за кодом примеров в https://firebase.google.com/docs/functions/callable, но он не включал c# образец.

1 Ответ

1 голос
/ 07 марта 2020

Я понял это. Сначала необходимо реализовать интерфейс IContinuation и IOnSuccessListener:

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. Однако забавная c - это задача java, и она не заблокирует поток задач. Net. Поэтому необходимо было вручную приостановить поток, используя TaskCompletionSource. IOnSuccessListener будет вызван, когда облачная функция вернется успешно. Затем 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);
    }
}
...