Облачная функция Firebase, вызываемая из Android, работает, но всегда получает нулевой ответ - PullRequest
0 голосов
/ 18 мая 2018

Я пытаюсь вызвать облачную функцию Google Firebase, которая просто использует транзакцию, чтобы проверить, что что-то существует в моем Firestore, а затем удалить это и еще один Документ.Я вызываю функцию из Android по нажатию кнопки, и она действительно работает, запись удалена, но ответ, который я получаю в Android, является нулевым, а не сообщения, которые я пытаюсь отправить обратно.

Функция облака:

//Takes in the uid of the user who sent the request and the user who received it,
// and deletes the request
exports.cancelFriendRequest = functions.https.onCall((data, context) => {
    //Grab the parameters
    const sender = data.sender;
    const recipient = data.recipient;

    //Ensure parameters are good
    if(sender === undefined || sender === "" || recipient === undefined || recipient === "") {
        return res.status(400).send("Invalid arguments.");
    }

    const db = admin.firestore();

    //Build document references to check that friend request exists
    let receivedFriendRequestDocRef = db.doc("users/"+recipient+"/receivedFriendRequests/"+sender);
    let sentFriendRequestDocRef = db.doc("users/"+sender+"/sentFriendRequests/"+recipient);

    db.runTransaction(transaction => {
        return transaction.getAll(receivedFriendRequestDocRef, sentFriendRequestDocRef).then(docs => {
            //Check that the friend request exists
            if(!docs[0].exists) {
                return Promise.reject(new Error("Friend request does not exist."));
            }

            //Delete friend requests
            transaction.delete(receivedFriendRequestDocRef);
            transaction.delete(sentFriendRequestDocRef);

            return Promise.resolve("Friend request deleted successfully.");
        });
    }).then(result => {
        //I've also tried return res.status(200).send("Success: " + result);
        //But that wasn't working so I thought I'd try this, which I saw in a Google sample git repo
        return "Success: " + result;
    }).catch(err => {
        return err.toString();
    });
});

Вызов функции облака Android:

public static Task<String> cancelFriendRequest(String sender, String recipient) {
        FirebaseFunctions mFunctions = FirebaseFunctions.getInstance();

        //Create the arguments to the callable function
        Map<String, Object> data = new HashMap<>();
        data.put("sender", sender);
        data.put("recipient", recipient);

        return mFunctions
                .getHttpsCallable("cancelFriendRequest")
                .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.
                        String result = (String) task.getResult().getData();
                        return result;
                    }
                });
    }

Функция в Android, которая вызывает функцию облака:

private static void cancelFriendRequest(String uid) {
    String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
    CloudFunctions.cancelFriendRequest(userId, uid).addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
            String result = task.getResult();
            Log.e("Result", "" + result);
            Snackbar.make(mRecyclerView, result, Snackbar.LENGTH_LONG).show();
        }
    });
}

Я счастливпредоставить больше информации.Я также нашел вызов функции очень медленно.Это работает очень быстро, если я установлю его на onRequest и вызову его, перейдя по URL-адресу вручную, но onCall и вызов с Android мучительно медленны.В любом случае, это еще одна проблема, спасибо!

РЕДАКТИРОВАТЬ: Кроме того, выскакивает Снэк-бар (пустой, потому что он возвращает ноль), за 10-15 секунд до того, как документы фактически удалены из базы данных.

1 Ответ

0 голосов
/ 18 мая 2018

Вы пропустили возврат в своей основной функции (в коде облачной функции), поэтому функция возвращается до завершения транзакции.Из документации :

Используйте эти рекомендуемые подходы для управления жизненным циклом ваших функций:

Разрешение функций, выполняющих асинхронную обработку (также называемых "фоновыми функциями""), возвращая обещание JavaScript.

Попробуйте вернуть транзакцию (return db.runTransaction(transaction => {....});), и она должна работать следующим образом:

//Takes in the uid of the user who sent the request and the user who received it,
// and deletes the request
exports.cancelFriendRequest = functions.https.onCall((data, context) => {
    //Grab the parameters
    const sender = data.sender;
    const recipient = data.recipient;

    //Ensure parameters are good
    if(sender === undefined || sender === "" || recipient === undefined || recipient === "") {
        return res.status(400).send("Invalid arguments.");
    }

    const db = admin.firestore();

    //Build document references to check that friend request exists
    let receivedFriendRequestDocRef = db.doc("users/"+recipient+"/receivedFriendRequests/"+sender);
    let sentFriendRequestDocRef = db.doc("users/"+sender+"/sentFriendRequests/"+recipient);

   return db.runTransaction(transaction => {
        return transaction.getAll(receivedFriendRequestDocRef, sentFriendRequestDocRef).then(docs => {
            //Check that the friend request exists
            if(!docs[0].exists) {
                return Promise.reject(new Error("Friend request does not exist."));
            }

            //Delete friend requests
            transaction.delete(receivedFriendRequestDocRef);
            transaction.delete(sentFriendRequestDocRef);

            return Promise.resolve("Friend request deleted successfully.");
        });
    }).then(result => {
        //I've also tried return res.status(200).send("Success: " + result);
        //But that wasn't working so I thought I'd try this, which I saw in a Google sample git repo
        return "Success: " + result;
    }).catch(err => {
        return err.toString();
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...