【问题标题】:How to get the device token only once the user downloads the application?如何仅在用户下载应用程序后获取设备令牌?
【发布时间】:2019-12-21 04:56:38
【问题描述】:

我有一个监听 Firebase 存储的云功能,每当我上传文档时,它都会监听它,并根据文档提供的数据更新 Firestore。

现在,我想在每次上传文档时通知用户,所以我在同一个云功能中添加了推送通知的功能,并创建了一个服务设备令牌,存储在设备集合中,遍历集合并发送通知。

我遇到的问题是,每次打开应用程序时,我的 Firstore 中的写入都会增加 1,我认为它来自通知的错误实现。

我应该只在用户下载应用程序后才写入令牌,但似乎每次初始化应用程序时都会写入令牌。

我可以看到每当应用程序初始化时我都在调用该函数,我尝试使用 if 语句检查令牌是否已经存在,如果存在则不返回任何内容,否则将其写入集合,但它没有t 似乎工作正常。

这是我的代码,请告诉我我做错了什么。

这是我的云功能:

exports.addFile = functions.storage.object().onFinalize(object => {
    if (object && object.name) {


     ........... // perform the initial process

        }).then(() => {
            console.log('Data is stored');
            setTimeout(async () => {
                // SEND NOTIFICATION 
                //NOTIFICATION CONTENT 
                const payLoad = {
                    notification: {
                        title: 'New Cat',
                        body: `Check it out!`,
                        sound: 'Enabled'
                    },
                }
                // COLLECTION REFERENCE
                const colRef = db.collection('Devices');

                // device reference 
             const deviceRef = colRef.where('userId', '==','testUserId');

                // get users tokens and send notification 
                const devices = await deviceRef.get();
                const tokens: any = [];

                //loop over documents 
                devices.forEach(result => {
                    const token = result.data().token;
                    tokens.push(token);
                });
                console.log('tokens', tokens);

                //Send Notifications 
                return admin.messaging().sendToDevice(tokens, 
                 payLoad).then(response => {
                    // check if there is an error for each message 
                    response.results.forEach((result, index) => {
                    const error = result.error;
                      if (error) {
                            console.error('Failure sending notification 
                             to', tokens[index], error);
                        if (error.code === 'messaging/invalid- 
                         registration-token' ||
                          error.code === 'messaging/registration- 
                          token-not-registered') {
                        colRef.doc(tokens[index]).delete().then(() => {
                         console.log(tokens[index], 'have been deleted');
                               }).catch(err => {
                                    console.log(err);
                                })
                            }

                        }
                    })
                })
            }, 5000);

        })
    } 
   }
    return;
}
);

这是我的通知服务:

  // GET TOKEN
  async getToken() {
    let token;
    if (this.platform.is('android')) {
      token = await this.firebase.getToken();
      console.log('token', token);
    }
  if (this.platform.is('ios')) {
     token = await this.firebase.getToken();
     await this.firebase.grantPermission();
   }

    this.saveToken(token);
  }

 private saveToken(token) {
   if (!token) { return; }

   const devicesRef = this.afs.collection('Devices');

   const data = {
     token,
   };
   if (token === devicesRef.doc(token)) {
     return;
   } else {
     return devicesRef.doc(token).set(data);
   }
  }

  onNotifications() {
  return this.firebase.onMessageReceived();
 }

最后,app.ts 中的代码:

  private async presentToast(message) {
    const toast = await this.toastController.create({
      message,
      duration: 3000
    });
    toast.present();
    }
    private notificationSetup() {
    this.nS.getToken();
    this.nS.onNotifications().subscribe(
      (msg) => {
        if (this.platform.is('ios')) {
      this.presentToast(msg.aps.alert);
        } else {
          this.presentToast(msg.body);
        }
      });
   }

initializeApp(){
   this.platform.ready().then(() => {
   this.statusBar.styleDefault();
   this.splashScreen.hide();
   this.notificationSetup();
   timer(3000).subscribe(() => {
    this.showSplash = false;
  });
});

【问题讨论】:

    标签: angular firebase google-cloud-firestore google-cloud-functions ionic4


    【解决方案1】:

    我可以在这里找到两件事:

    1. 您希望用户知道您何时上传文件。

    2. 您只想在用户下载应用程序时存储您的令牌,但每次打开应用程序时都会存储它。

    我可以帮助解决第一个问题。

    这听起来像是您想使用触发器。 Check this other answer,我觉得和你想做的差不多。

    【讨论】:

    • 您好,感谢您的回答。我已经想到了第一个,唯一的问题是数字 2。我不确定令牌是否应该写入一次,或者它们是否过期并在每次应用程序初始化时写入。
    猜你喜欢
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 2012-12-15
    • 2012-10-02
    • 1970-01-01
    相关资源
    最近更新 更多