javascript - Storing FCM tokens online - Stack Overflow

I am working with an iOS app which calls an Firebase cloud function, to store FCM tokens, for later use

I am working with an iOS app which calls an Firebase cloud function, to store FCM tokens, for later use when sending notifications. The problem is that it does not work.

I am using a Cloud Firestore database.

When the function is called, here is what I want to happen. The function checks the parameters against a database. If the data in the provided parameter is already found in the DB then nothing should happen. If it is not found, then it should be added to the DB.

My cloud function code is below. I would be glad if someone could help me find the precise issue.

exports.addNewElement = functions.https.onCall((data, context) => {
  console.log('--addNewElement-- has been called with:\n' + data.fcmToken + '\n!!');
  var collectionRef = db.collection("THE_COLLECTION");

  // Create a query against the collection.
  var query = collectionRef.where("fcmToken", "==", data.fcmToken);
  query.get().then(function(doc) {
    if (doc.exists) { // We should do nothing.
        console.log("Document data:", doc.data());
    } else { // We should add the new element.
        // doc.data() will be undefined in this case
        console.log("No such document!");
        collectionRef.add({"fcmToken": fcmToken})
    }
  }).catch(function(error) {
    console.log("Error getting document:", error);
  });
});

I could imagine other directions to handle FCM tokens. Is there any remend way to use as best practice?

I am working with an iOS app which calls an Firebase cloud function, to store FCM tokens, for later use when sending notifications. The problem is that it does not work.

I am using a Cloud Firestore database.

When the function is called, here is what I want to happen. The function checks the parameters against a database. If the data in the provided parameter is already found in the DB then nothing should happen. If it is not found, then it should be added to the DB.

My cloud function code is below. I would be glad if someone could help me find the precise issue.

exports.addNewElement = functions.https.onCall((data, context) => {
  console.log('--addNewElement-- has been called with:\n' + data.fcmToken + '\n!!');
  var collectionRef = db.collection("THE_COLLECTION");

  // Create a query against the collection.
  var query = collectionRef.where("fcmToken", "==", data.fcmToken);
  query.get().then(function(doc) {
    if (doc.exists) { // We should do nothing.
        console.log("Document data:", doc.data());
    } else { // We should add the new element.
        // doc.data() will be undefined in this case
        console.log("No such document!");
        collectionRef.add({"fcmToken": fcmToken})
    }
  }).catch(function(error) {
    console.log("Error getting document:", error);
  });
});

I could imagine other directions to handle FCM tokens. Is there any remend way to use as best practice?

Share Improve this question edited Dec 14, 2018 at 10:42 droidBomb 8805 silver badges8 bronze badges asked Dec 3, 2018 at 6:45 MichelMichel 11.8k21 gold badges102 silver badges219 bronze badges 4
  • What's the problem? – Frank van Puffelen Commented Dec 3, 2018 at 7:01
  • The problem is that I am not storing anything now. Because what I do is not working. Beside, I am not sure the way I want to do it is the best practice. I could store the token by making DB write request directly from the app, I have already tried successfully, but I would like to avoid storing twice the same token, that is why I thought using a cloud function might be a better approach. – Michel Commented Dec 3, 2018 at 7:14
  • why you used collectionRef.add({"fcmToken": fcmToken}) insted of collectionRef.add({"fcmToken": data.fcmToken}) – Jatin Kathrotiya Commented Dec 3, 2018 at 7:20
  • Right! This was a mistyping. Sorry! – Michel Commented Dec 3, 2018 at 8:28
Add a ment  | 

1 Answer 1

Reset to default 5

I take a bit of a different approach. I have an ionic app and after the app has registered with FCM (we have FCM token), I add the token to a 'devices' collection straight from the app. This way, a user can log in to more then one device and we will have the token for each device enabling us to send the message to each device. If you want to send a message to a user, you query the devices collection for that uid to get all the tokens for that user

Saving the token:

    private saveTokenToFirestore(person: Person, token) {
        if (!token) return;
        const devicesRef = this.afs.collection('devices')

        const docData = { 
          token,
          userId: person.id,
        }

        return devicesRef.doc(token).set(docData)
      }

where person.id is the firebase uid.

I then use firebase functions to monitor some nodes to figure out when to send FCM messages.

e.g. we have teams with persons as members and they can chat to each other. When a person sends a message to a team, each team member (except the sender himself) needs to get a notification.

Sending a notification to all members except the sender himself:

exports.chatMessageOnCreateSendFcm = functions.firestore
    .document('chatGroups/{teamId}/messages/{messageId}')
    .onCreate(async (snap, context) => {
        const data = snap.data();
        const teamId = context.params.teamId;
        const name = data.pName;
        const message = data.msg;
        const userId = data.pId;

        // Notification content
        const payload = {
            notification: {
                title: name,
                body: message,
            }
        }

        const db = admin.firestore();

        // get the team (chatGroup)
        const teamRef = db.collection('teams').doc(teamId);
        const teamSnapshot = await teamRef.get();
        const team = teamSnapshot.data();
        const devicesRef = db.collection('devices');
        const queries: Promise<FirebaseFirestore.QuerySnapshot>[] = team.members
            .filter(f => f.id !== userId)
            .map(member => {
                return devicesRef.where('userId', '==', member.id).get();
            });

        return Promise.all(queries)
            .then((querySnapshots) => {
                const tokens = [];
                querySnapshots.forEach(snapShot => {
                    if (snapShot) {
                        snapShot.docs.forEach(doc => {
                            if (doc) {
                                const token = doc.data().token;
                                if (token) {
                                    tokens.push(token);
                                }
                            }
                        })
                    }
                });

                if (tokens.length === 0) {
                    return Promise.resolve(null);
                } else {
                    return admin.messaging().sendToDevice(tokens, payload);
                }
            })
            .catch(err => {
                console.error(err);
                return Promise.resolve(null);
            });
    });

You can modify the above to suit your needs. Hope it helps

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745402452a4626163.html

相关推荐

  • javascript - Storing FCM tokens online - Stack Overflow

    I am working with an iOS app which calls an Firebase cloud function, to store FCM tokens, for later use

    3小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信