Benno Staub
Benno Staub

Reputation: 33

Firebase Functions: Client network socket disconnected error for push notification sent via FCM

I am using firebase cloud functions to send push notifications to my ionic app. In the early days, everything worked fine but lately a new error has started to emerge as shown below. It just occurs randomly (in my mind) in the functions execution which leads then to no push notification sent.

I contacted Firebase support and they explained that it must be something with my firewall because it cannot make the connection or something, BUT the code is deployed via firebase so it's not my laptop executing the function but a google cloud function executed on the cloud, so IF that's the problem, then it must be on their side which they don't understand, or am I wrong?

Anyway, here's the error and the code which I deployed via the command 'firebase deploy --only functions', no errors shown during the deployment.

Code:

exports.sendDebugPush = functions.pubsub.schedule('* * * * *').onRun((context) => {
    console.log('Bun');
    admin.database().ref('/users/R1CFRqnvsmdJtxIJZIvgF1Md0lr1').once("value", function(user) {
        let todos = [];
        for(let key in user.val().nextActions) {
            if(user.val().nextActions[key].active != false) {
                let todo = user.val().nextActions[key]
                todo['todoid'] = key;
                todos.push(todo);
            }
        }
        if(todos.length > 0) {
            //currently we pick a random todo, later on the one with the highest priority
            //todos.sort((a, b) => (a.priority/1 < b.priority/1) ? 1 : -1);
            let randomTodo = todos[Math.floor(Math.random()*todos.length)]      
            let payload = {
                notification: {
                    title: "Gossik",
                    body: "Hoiiiii"
                },
                data: {
                    title: "Gossik",
                    body: "Hoiiiii",
                    target: 'todo',
                    todoid: randomTodo.todoid
                }
            };
            admin.database().ref('/users/' + user.key + '/devices').once("value", function(devices) {
                devices.forEach(function(device) {
                    admin.messaging().sendToDevice(device.val(), payload)
                    .catch(err => {
                        console.log('caaaatchiiiiiing');
                        console.log(err);
                    });
                });
            });
            let pushNotification = {
                message: "Hoiiiii",
                todoid: randomTodo.todoid,
                createDate: new Date().toISOString()
            }
            admin.database().ref('/users/' + user.key + '/pushNotifications').push(pushNotification);
        }
    });
    return null;
});

The error happens at this line:

admin.messaging().sendToDevice(device.val(), payload)

Everything else works fine, even the code afterwards where I push the notifications to my database, so I get a new entry in my database but no push notifications on the phone.

Error:

{ Error: Error while making request: Client network socket disconnected before secure TLS connection was established. Error code: ECONNRESET
at FirebaseAppError.FirebaseError [as constructor] (/workspace/node_modules/firebase-admin/lib/utils/error.js:42:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (/workspace/node_modules/firebase-admin/lib/utils/error.js:88:28)
at new FirebaseAppError (/workspace/node_modules/firebase-admin/lib/utils/error.js:123:28) 
at /workspace/node_modules/firebase-admin/lib/utils/api-request.js:209:19 
at process._tickCallback (internal/process/next_tick.js:68:7)
errorInfo: 
{ code: 'app/network-error',
message: 
'Error while making request: Client network socket disconnected before secure TLS connection was established. Error code: ECONNRESET' },
codePrefix: 'app' } 

Very appreciate any help with that, thanks!

Upvotes: 0

Views: 1687

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317712

You code is uniformly not handling promises correctly. Every time you call an asynchronous API that returns a promise, that promise needs to be fully resolved before your function terminates. If you don't wait for the promises to resolve, then it's entirely possible that the async work might never complete, as Cloud Functions will terminate the code before it's done. Please read the documenation about this.

Since your function just returns null immediately, it is not waiting for any of the work to complete. This includes the calls to FCM and the database read. You will have to rewrite this function so that it returns a new promise that resolves only after all the other promises have resolved.

Upvotes: 1

Related Questions