如何仅在用户下载应用程序后获取设备令牌?
Posted
技术标签:
【中文标题】如何仅在用户下载应用程序后获取设备令牌?【英文标题】: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;
);
);
【问题讨论】:
【参考方案1】:我可以在这里找到两件事:
您希望用户知道您何时上传文件。
您只想在用户下载应用程序时存储您的令牌,但每次打开应用程序时都会存储它。
我可以帮助解决第一个问题。
这听起来像是您想使用触发器。 Check this other answer,我觉得和你想做的差不多。
【讨论】:
您好,感谢您的回答。我已经想到了第一个,唯一的问题是数字 2。我不确定令牌是否应该写入一次,或者它们是否过期并在每次应用程序初始化时写入。以上是关于如何仅在用户下载应用程序后获取设备令牌?的主要内容,如果未能解决你的问题,请参考以下文章