Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloud function Error #72

Open
tobimichigan opened this issue Feb 13, 2019 · 15 comments
Open

Cloud function Error #72

tobimichigan opened this issue Feb 13, 2019 · 15 comments

Comments

@tobimichigan
Copy link

Hi there developers,

I recently started working on this repo and set it up successfully but during the cloud function deployment, issues sprung up:

Original from repo
index.js
`const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const actionTypeNewLike = "new_like";
const actionTypeNewComment = "new_comment";
const actionTypeNewPost = "new_post";
const notificationTitle = "Social App";

const followingPosDbValue = "following_post";
const followingPosDbKey = "followingPostsIds";
const followingsDbKey = "followings";
const followersDbKey = "followers";
const followingDbKey = "follow";

const postsTopic = "postsTopic";

const THUMB_MEDIUM_SIZE = 1024; //px
const THUMB_SMALL_SIZE = 100; //px

const THUMB_MEDIUM_DIR = "medium";
const THUMB_SMALL_DIR = "small";

const gcs = require('@google-cloud/storage')();
const path = require('path');
const sharp = require('sharp');
const os = require('os');
const fs = require('fs');

exports.pushNotificationLikes = functions.database.ref('/post-likes/{postId}/{authorId}/{likeId}').onCreate((snap, context) => {

console.log('New like was added');

const likeAuthorId = context.params.authorId;
const postId = context.params.postId;

// Get liked post.
const getPostTask = admin.database().ref(`/posts/${postId}`).once('value');

return getPostTask.then(post => {

    if (likeAuthorId === post.val().authorId) {
        console.log('User liked own post');
        return 'User liked own post';
    }

    // Get the list of device notification tokens.
    const getDeviceTokensTask = admin.database().ref(`/profiles/${post.val().authorId}/notificationTokens`).once('value');
    console.log('getDeviceTokensTask path: ', `/profiles/${post.val().authorId}/notificationTokens`);

    // Get like author.
    const getLikeAuthorProfileTask = admin.database().ref(`/profiles/${likeAuthorId}`).once('value');

    return Promise.all([getDeviceTokensTask, getLikeAuthorProfileTask]).then(results => {
        const tokensSnapshot = results[0];
        const likeAuthorProfile = results[1].val();

        // Check if there are any device tokens.
        if (!tokensSnapshot.hasChildren()) {
            return console.log('There are no notification tokens to send to.');
        }

        console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.');
        console.log('Fetched like Author profile', likeAuthorProfile);

        // Create a notification
        const payload = {
            data: {
                actionType: actionTypeNewLike,
                title: notificationTitle,
                body: `${likeAuthorProfile.username} liked your post`,
                icon: post.val().imagePath,
                postId: postId,

            },
        };

        // Listing all tokens.
        const tokens = Object.keys(tokensSnapshot.val());
        console.log('tokens:', tokens[0]);

        // Send notifications to all tokens.
        return admin.messaging().sendToDevice(tokens, payload).then(response => {
            // For each message check if there was an error.
            const tokensToRemove = [];
            response.results.forEach((result, index) => {
                const error = result.error;
                if (error) {
                    console.error('Failure sending notification to', tokens[index], error);
                    // Cleanup the tokens who are not registered anymore.
                    if (error.code === 'messaging/invalid-registration-token' ||
                        error.code === 'messaging/registration-token-not-registered') {
                        tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
                    }
                }
            });
            return Promise.all(tokensToRemove);
        });
    }).catch((fallback) => {
        console.error('Failure getPostTask', fallback);
    });
}).catch((fallback) => {
    console.error('Failure getPostTask', fallback);
})

});

exports.pushNotificationComments = functions.database.ref('/post-comments/{postId}/{commentId}').onCreate((snap, context) => {

const commentId = context.params.commentId;
const postId = context.params.postId;
const comment = snap.val();

console.log('New comment was added, id: ', postId);

// Get the commented post .
const getPostTask = admin.database().ref(`/posts/${postId}`).once('value');

return getPostTask.then(post => {

    // Get the list of device notification tokens.
    const getDeviceTokensTask = admin.database().ref(`/profiles/${post.val().authorId}/notificationTokens`).once('value');
    console.log('getDeviceTokensTask path: ', `/profiles/${post.val().authorId}/notificationTokens`);

    // Get post author.
    const getCommentAuthorProfileTask = admin.database().ref(`/profiles/${comment.authorId}`).once('value');
    console.log('getCommentAuthorProfileTask path: ', `/profiles/${comment.authorId}`);

    return Promise.all([getDeviceTokensTask, getCommentAuthorProfileTask]).then(results => {
        const tokensSnapshot = results[0];
        const commentAuthorProfile = results[1].val();

        if (commentAuthorProfile.id === post.val().authorId) {
            console.log('User commented own post');
            return 'User commented own post';
        }

        // Check if there are any device tokens.
        if (!tokensSnapshot.hasChildren()) {
            console.log('There are no notification tokens to send to.');
            return 'There are no notification tokens to send to.';
        }

        console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.');

        // Create a notification
        const payload = {
            data: {
                actionType: actionTypeNewComment,
                title: notificationTitle,
                body: `${commentAuthorProfile.username} commented your post`,
                icon: post.val().imagePath,
                postId: postId,
            },
        };

        // Listing all tokens.
        const tokens = Object.keys(tokensSnapshot.val());
        console.log('tokens:', tokens[0]);

        // Send notifications to all tokens.
        return admin.messaging().sendToDevice(tokens, payload).then(response => {
            // For each message check if there was an error.
            const tokensToRemove = [];
            response.results.forEach((result, index) => {
                const error = result.error;
                if (error) {
                    console.error('Failure sending notification to', tokens[index], error);
                    // Cleanup the tokens who are not registered anymore.
                    if (error.code === 'messaging/invalid-registration-token' ||
                        error.code === 'messaging/registration-token-not-registered') {
                        tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
                    }
                }
            });
            return Promise.all(tokensToRemove);
        });
    }).catch((fallback) => {
        console.error('Failure getPostTask', fallback);
    });
}).catch((fallback) => {
    console.error('Failure getPostTask', fallback);
})

});

exports.pushNotificationNewPost = functions.database.ref('/posts/{postId}').onCreate((snap, context) => {
const postId = context.params.postId;

console.log('New post was created');

// Get post authorID.
const getAuthorIdTask = admin.database().ref(`/posts/${postId}/authorId`).once('value');

return getAuthorIdTask.then(authorId => {

    console.log('post author id', authorId.val());

    // Create a notification
    const payload = {
        data: {
            actionType: actionTypeNewPost,
            postId: postId,
            authorId: authorId.val(),
        },
    };

    // Send a message to devices subscribed to the provided topic.
    return admin.messaging().sendToTopic(postsTopic, payload).then(response => {
        // See the MessagingTopicResponse reference documentation for the
        // contents of response.
        console.log("Successfully sent info about new post :", response);
        return response;
    })
        .catch(error => {
            console.log("Error sending info about new post:", error);
        });
}).catch(fallback => {
    console.error('Failure getPostTask', fallback);
});

});

exports.addNewPostToFollowers = functions.database.ref('/posts/{postId}').onCreate((snap, context) => {
const postId = context.params.postId;

console.log('New post was created');

// Get post authorID.
const getAuthorIdTask = admin.database().ref(`/posts/${postId}/authorId`).once('value');

return getAuthorIdTask.then(authorId => {

    console.log('post author id', authorId.val());

    // Get followers ids.
    return admin.database().ref().child(followingDbKey).child(authorId.val()).child(followersDbKey).once('value', function(snapshot) {
        snapshot.forEach(function (childSnapshot) {
            let followerId = childSnapshot.val().profileId;
            console.log('setNewPostValuesToFollower', "followerId:", followerId, "postId:", postId);

            admin.database().ref().child(followingPosDbKey).child(followerId).child(postId).set({
                postId:postId
            });
        });
    }).catch(fallback => {
        console.error('Failure get followers ids', fallback);
    });

}).catch(fallback => {
    console.error('Failure getPostTask', fallback);
});

});

exports.removePostFromFollowingList = functions.database.ref('/posts/{postId}').onDelete((snap, context) => {
const postId = context.params.postId;
const authorId = snap.val().authorId;

// Get followers ids.
return admin.database().ref().child(followingDbKey).child(authorId).child(followersDbKey).once('value', function(snapshot) {
    snapshot.forEach(function (childSnapshot) {
        let followerId = childSnapshot.val().profileId;
        admin.database().ref().child(followingPosDbKey).child(followerId).child(postId).remove();
        console.log('remove post if from following list for followerId:', followerId, "postId:", postId);
    });
}).catch(fallback => {
    console.error('Failure get followers ids', fallback);
});

});

exports.generateThumbnail = functions.storage.object().onFinalize((object) => {
const fileBucket = object.bucket; // The Storage bucket that contains the origin file.
const filePath = object.name; // File path in the bucket.
const contentType = object.contentType; // File content type.

const generateThumbsPromises = generateThumbnailsGeneral(fileBucket, filePath, contentType);

if(generateThumbsPromises !== null) {
    return generateThumbsPromises.then(() => {
        console.log('Thumbnail created successfully');
        return null;
    })
} else {
    return null;
}

});

function generateThumbnailsGeneral(fileBucket, filePath, contentType) {
console.log("fileBucket", fileBucket);
console.log("filePath", filePath);
console.log("contentType", contentType);

// Exit if this is triggered on a file that is not an image.
if (!contentType.startsWith('image/')) {
    console.log('This is not an image.');
    return null;
}

// Get the dir name.
const dirname = path.dirname(filePath);
if (dirname.includes(THUMB_MEDIUM_DIR) || dirname.includes(THUMB_SMALL_DIR)) {
    console.log('Already scaled.');
    return null;
}

// Download file from bucket.

const fileName = path.basename(filePath);

const tempFilePath = path.join(os.tmpdir(), fileName);
const bucket = gcs.bucket(fileBucket);

return bucket.file(filePath)
    .download({
        destination: tempFilePath
    })
    .then(() => {
        console.log('download origin file successfully');
        const mediumThumbPromise = createThumb(fileName, filePath, tempFilePath, THUMB_MEDIUM_DIR, THUMB_MEDIUM_SIZE, bucket);
        const smallThumbPromise = createThumb(fileName, filePath, tempFilePath, THUMB_SMALL_DIR, THUMB_SMALL_SIZE, bucket);
        return Promise.all([mediumThumbPromise, smallThumbPromise])
    })
    .then(() => {
        fs.unlinkSync(tempFilePath);
        console.log(`removing origimal temp file complete`);
        return null;
    });

}

function createThumb(fileName, originFilePath, tempFilePath, thumbDir, size, bucket) {
const newFileTemp = path.join(os.tmpdir(), ${fileName}_${size}_tmp.jpg);
const newFilePath = path.join(path.dirname(originFilePath), thumbDir, fileName);

return sharp(tempFilePath)
    .resize(size, size)
    .max()
    .toFile(newFileTemp)
    .then(info => {
        console.log(`resize ${size} complete, filePath = ${newFilePath}`);
        return bucket.upload(newFileTemp, {
            destination: newFilePath
        })
    })
    .then(() => {
        fs.unlinkSync(newFileTemp);
        console.log(`removing thumb temp file for size ${size} px is complete`);
        return null;
    });

}
socialapp_cloudfunctinerr

Please is anyone there with good pointers as to why this error occurs?
`

@Batishev-Rozdoum
Copy link
Contributor

Hi @tobimichigan ! What Node.js version do you use? Try to use Node.js 6

@sourimoto
Copy link

I have the same problem to):

@sourimoto
Copy link

seems to bee the problem with this line
//const gcs = require('@google-cloud/storage')();
comment this line and deploy the functions >but only the like and the comment fun will work

@tobimichigan

@sourimoto
Copy link

@Batishev-Rozdoum what you say about that ?

@tobimichigan
Copy link
Author

@Batishev-Rozdoum , I dont think this is a node version issue. You should be aware that google is often updating their cloud functionalities. I am still debugging your repo and will give feedback shortly. @sourimoto I don't think your solution is practicable cos of runtime bugs.

@sourimoto
Copy link

@tobimichigan i don't have any runtime error, but I think the problem set in the billing

@Tanv33rA
Copy link

i am also facing this issue . did any one solve this ?

@ghost
Copy link

ghost commented Mar 24, 2019

i am also facing problem
@Batishev-Rozdoum @Batishev-Rozdoum
can u tell us the how to use this without deploying it in your way

i mean to say is their any other method

@Tanv33rA
Copy link

@shyamguptaa i have successfully uploaded cloud functions except generateThumnail by modifying index.js file.

@Taiti77
Copy link

Taiti77 commented Apr 10, 2019

Google sign in method didn't work on Android 8.0 (API level 26 or later), for Android 5.1 (API level 22) it's working fine.
Any help?

@tab0786
Copy link

tab0786 commented May 20, 2019

@shyamguptaa i have successfully uploaded cloud functions except generateThumnail by modifying index.js file.

please upload updated Index.js file

@Batishev-Rozdoum
Copy link
Contributor

Hi guys!
I think I've found the problem. Existing index.js file contains functions in JavaScript, not in TypeScript. Maybe during Functions Setup you choose TypeScript? In this case you can received this type of error.

Just in case, here is my parameters for working functions:
Node version v8.9.1
Python 2.7.12

? What language would you like to use to write Cloud Functions? JavaScript
? Do you want to use ESLint to catch probable bugs and enforce style? Yes
? File functions/package.json already exists. Overwrite? No
i Skipping write of functions/package.json
✔ Wrote functions/.eslintrc.json
? File functions/index.js already exists. Overwrite? No
i Skipping write of functions/index.js
✔ Wrote functions/.gitignore
? Do you want to install dependencies with npm now? Yes

Hope it helps

@Tanv33rA
Copy link

@shyamguptaa i have successfully uploaded cloud functions except generateThumnail by modifying index.js file.

please upload updated Index.js file

just remove the thumbnails function and rest of functions will work.

@omaisali
Copy link

I Solved by const gcs = require('@google-cloud/storage');
(without () at the end of each statement)

@SaiVenkatPavan
Copy link

Hi guys!
I think I've found the problem. Existing index.js file contains functions in JavaScript, not in TypeScript. Maybe during Functions Setup you choose TypeScript? In this case you can received this type of error.

Just in case, here is my parameters for working functions:
Node version v8.9.1
Python 2.7.12

? What language would you like to use to write Cloud Functions? JavaScript
? Do you want to use ESLint to catch probable bugs and enforce style? Yes
? File functions/package.json already exists. Overwrite? No
i Skipping write of functions/package.json
✔ Wrote functions/.eslintrc.json
? File functions/index.js already exists. Overwrite? No
i Skipping write of functions/index.js
✔ Wrote functions/.gitignore
? Do you want to install dependencies with npm now? Yes

Hope it helps

no that's not the problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants