【问题标题】:Storing FCM tokens online在线存储 FCM 代币
【发布时间】:2018-12-03 06:45:15
【问题描述】:

我正在使用一个调用 Firebase 云函数的 iOS 应用程序来存储 FCM 令牌,以便以后在发送通知时使用。问题是它不起作用。

我正在使用 Cloud Firestore 数据库。

当函数被调用时,这就是我想要发生的事情。该函数根据数据库检查参数。如果提供的参数中的数据已经在数据库中找到,那么什么都不会发生。 如果未找到,则应将其添加到数据库中。

我的云功能代码如下。如果有人能帮我找到确切的问题,我会很高兴。

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);
  });
});

我可以想象处理 FCM 令牌的其他方向。 有什么推荐的方法可以用作最佳实践吗?

【问题讨论】:

  • 有什么问题?
  • 问题是我现在没有存储任何东西。因为我所做的没有工作。此外,我不确定我想要的方式是最佳实践。我可以通过直接从应用程序发出数据库写入请求来存储令牌,我已经尝试过成功,但我想避免存储两次相同的令牌,这就是为什么我认为使用云功能可能是更好的方法。跨度>
  • 你为什么使用collectionRef.add({"fcmToken": fcmToken}) insted of collectionRef.add({"fcmToken": data.fcmToken})
  • 对!这是一个错误的输入。对不起!

标签: javascript ios firebase firebase-cloud-messaging


【解决方案1】:

我采取了一些不同的方法。我有一个离子应用程序,在应用程序向 FCM 注册后(我们有 FCM 令牌),我直接从应用程序将令牌添加到“设备”集合中。这样,用户可以登录多个设备,我们将拥有每个设备的令牌,使我们能够将消息发送到每个设备。如果要向用户发送消息,请查询该 uid 的设备集合以获取该用户的所有令牌

保存令牌:

    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)
      }

其中 person.id 是 firebase uid。

然后我使用 firebase 函数来监控一些节点以确定何时发送 FCM 消息。

例如我们有团队成员,他们可以互相聊天。当一个人向团队发送消息时,每个团队成员(发送者本人除外)都需要收到通知。

向除发件人本人以外的所有成员发送通知:

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);
            });
    });

您可以修改以上内容以满足您的需要。希望对你有帮助

【讨论】:

  • 好的。为什么不呢,但在这种方法中,您最终可能会在 DB 中获得多次相同的 fcm 令牌?告诉我我是否错了。或者也许你只是不在乎?
  • 您不会多次得到相同的令牌,因为令牌是集合的键。如果不存在,它将插入,如果存在则更新/替换(doc.set 是一个 upsert 操作)您最终可能会得到具有相同 uid 的集合,例如,如果用户使用 iPhone 和 iPad 登录,这是正常的。他会在每台设备上收到通知
  • 当您使用“admin.messaging().sendToDevice(tokens, payload)”发送通知时;你可以在令牌中拥有大量物品吗?您没有使用所谓的“主题”吗?对吗?
  • 正确...我没有使用主题。在我的情况下,运动队本质上是少数且有限的成员。这取决于你对大的解释。我不建议使用它来发送数千个或更多的令牌。
  • 好的。所以对我来说使用主题更好。
猜你喜欢
  • 2017-12-20
  • 2023-03-12
  • 1970-01-01
  • 2021-01-04
  • 2019-08-06
  • 2018-05-04
  • 2015-09-17
  • 1970-01-01
  • 2011-03-16
相关资源
最近更新 更多