Android Firebase云功能通知

2023-12-03

我已成功设置 firebase 云功能来向主题发送通知。问题是它发送给包括发件人在内的所有用户,我如何设置我的云功能,以便它不向发件人显示通知?请帮忙?以下是我如何发送到主题

exports.sendNotesNotification = functions.database.ref('/Notes/{pushId}')
    .onWrite(event => {
        const notes = event.data.val();

        const payload = {
                notification: {

                    username: notes.username,
                    title: notes.title,
                    body: notes.desc

                }

            }

            admin.messaging().sendToTopic("New_entry", payload)
            .then(function(response){
                console.log("Successfully sent notes: ", response);
            })
            .catch(function(error){
                console.log("Error sending notes: ", error);
            });
        }); 

从 firebase 的文档来看,对于公开且时间不严格的通知,应该使用主题发送通知。在您的情况下,通知不是公开的,并且由于发件人也订阅了该特定主题,因此他也会收到通知。 因此,如果您想避免向发件人发送通知,您必须取消该发件人对您主题的订阅。

或者更好的解决方案是您应该使用 FCM 令牌将通知发送到单个设备。 用于发送 FCM 令牌通知的 node.js 代码是

admin.messaging().sendToDevice(<array of tokens>, payload);

您可以从 Android FirebaseInstanceIdService 的 onTokenRefresh() 方法获取设备令牌。

 @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        // TO DO: send token to your server or firebase database
}

Update:

将 firebase 令牌存储到数据库现在您应该像这样构建数据库

   -users
      |-user1uid
      |   |-name //your choice
      |   |-email //your choice
      |   |-fcmTokens
      |        |-valueOftoken1:true
      |        |-valueOftoken2:true
   -notes
      |  |-notesId
      |      |-yourdata
      |      |-createdBy:uidofUser  //user who created note
      |
   -subscriptions       //when onWrite() will trigger we will use this to get UID of all subscribers of creator of "note". 
      |      |-uidofUser    
      |           |-uidofSubscriber1:true //user subscribe to notes written. by parent node uid
      |           |-uidofSubscriber2:true

将令牌保存在数据库中的代码是onTokenRefresh()

 @Override
        public void onTokenRefresh() {
            // Get updated InstanceID token.
            String refreshedToken = FirebaseInstanceId.getInstance().getToken(); //get refreshed token
            FirebaseAuth mAuth = FirebaseAuth.getInstance();
            FirebaseUser user = mAuth.getCurrentUser(); //get currentto get uid
            if(user!=null){
            DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()); // create a reference to userUid in database
            if(refreshedToken!=null) //
              mDatabase.child("fcmTokens").child(refreshedToken).setValue(true); //creates a new node of user's token and set its value to true.
            else
              Log.i(TAG, "onTokenRefresh: token was null");
    }
    Log.d(tag, "Refreshed token SEND TO FIREBASE: " + refreshedToken);
    }

当为此用户创建新令牌时,上述代码将在用户的 fcmTokens 中创建新节点。

这是检索用户令牌并向这些令牌发送通知的 node.js 部分。 为了这

exports.sendNotesNotification = functions.database.ref('/Notes/{pushId}')
    .onWrite(event => {

        const notes = event.data.val();
        const createdby = notes.createdBy;
        const getAllSubscribersPromise = admin.database().ref(`/subscriptions/${createdby}/`).once('value'); // retrieving subscribers 

         const payload = {
                notification: {

                    username: notes.username,
                    title: notes.title,
                    body: notes.desc

                }

            }

        return getAllSubscribersPromise.then(result => {
        const userUidSnapShot = result; //results will have children having keys of subscribers uid.
        if (!userUidSnapShot.hasChildren()) {
          return console.log('There are no subscribed users to write notifications.'); 
        }
        console.log('There are', userUidSnapShot.numChildren(), 'users to send notifications to.');
        const users = Object.keys(userUidSnapShot.val()); //fetched the keys creating array of subscribed users

        var AllFollowersFCMPromises = []; //create new array of promises of TokenList for every subscribed users
        for (var i = 0;i<userUidSnapShot.numChildren(); i++) {
            const user=users[i];
            console.log('getting promise of user uid=',user);
            AllFollowersFCMPromises[i]= admin.database().ref(`/users/${user}/fcmToken/`).once('value');
        }

        return Promise.all(AllFollowersFCMPromises).then(results => {

            var tokens = []; // here is created array of tokens now ill add all the fcm tokens of all the user and then send notification to all these.
            for(var i in results){
                var usersTokenSnapShot=results[i];
                console.log('For user = ',i);
                if(usersTokenSnapShot.exists()){
                    if (usersTokenSnapShot.hasChildren()) { 
                        const t=  Object.keys(usersTokenSnapShot.val()); //array of all tokens of user [n]
                        tokens = tokens.concat(t); //adding all tokens of user to token array
                        console.log('token[s] of user = ',t);
                    }
                    else{

                    }
                }
            }
            console.log('final tokens = ',tokens," notification= ",payload);
            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 uid=', 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(usersTokenSnapShot.ref.child(tokens[index]).remove());
                        }
                    }
                    else{
                        console.log("notification sent",result);
                    }
                });

                return Promise.all(tokensToRemove);
            });

            return console.log('final tokens = ',tokens," notification= ",payload);
        });





            });
        }); 

我还没有检查 Node.js 部分,如果您仍然有问题,请告诉我。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android Firebase云功能通知 的相关文章

  • 如何获取每个StorageVolume的可用大小和总大小?

    背景 谷歌 悲伤 计划破坏存储权限 https www xda developers com android q storage access framework scoped storage 这样应用程序将无法使用标准文件 API 和文件
  • 我在布局上看不到任何 FirebaseRecyclerAdapter 项目

    我试图将数据从 Firebase 数据库检索到我的布局 但我看不到任何项目FirebaseRecyclerAdapter在布局中 请帮忙 我按照一个教程展示了如何做到这一点 当我运行应用程序时 我没有看到任何项目 但我可以滚动 public
  • 如何在android中显示保存在sdcard文件夹中的图像[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 当我正在显
  • 如何正确释放Android MediaPlayer

    我正在尝试向我的 Android 应用程序添加一个按钮 当点击该按钮时它会播放 MP3 我已经让它工作了 但没有办法释放 mediaPlayer 对象 因此即使在我离开活动后它仍然会继续播放 如果我在react 方法之外初始化MediaPl
  • Recyclerview 动态部分不使用任何第三个库

    我想将标头添加到 recyclerview 我正在尝试使用来实现它 Override public int getItemViewType int position depends on your problem if position 0
  • Dialog.setTitle 不显示标题

    我正在尝试向我的对话框添加自定义标题 但是每当我运行我的应用程序时 它都不会显示标题 我创建对话框的代码是 final Dialog passwordDialog new Dialog this passwordDialog setCont
  • 在 Cordova 应用程序中获取额外功能

    我们有两个 Android 应用程序 一个使用本机 Java 实现 另一个使用 Ionic 编写 Ionic 应用程序启动我的应用程序 这是使用灯插件 https github com lampaa com lampa startapp 我
  • ExoPlayer2 - 如何使 HTTP 301 重定向工作?

    我开始使用 ExoPlayer 来传输一些音频 一切都很顺利 直到我遇到一个带有 301 永久移动 重定向的 URL ExoPlayer2 默认情况下不处理该问题 我已经看过这个线程 https github com google ExoP
  • 图像作为电子邮件附件

    我想构建一个应用程序 我可以在电子邮件中附加图像 打开图像并将其设置为我的壁纸 我想让它跨平台 所以你能告诉我是否可以使用phonegap 或者我是否必须为iphone和android构建一个本机应用程序 您好 如果您只想通过电子邮件附加图
  • 从 BroadcastReceiver 类调用活动方法

    我知道我可以做一个内部接收器类来调用接收器中的任何方法 但我的主要活动太大了 要做的事情也很多 因此 我需要一个扩展广播接收器的类 但它不是内部类 并且可以从我的主要活动中调用一种方法 我不知道是否可能 但我的活动是家庭活动和 single
  • Android - AudioRecord类不读取数据,audioData和fftArray返回零

    我是 Android 新手 一直在开发音调分析器应用程序 最低 SDK 8 我读了很多关于如何实现 Audiorecord 类的文章 但我想知道为什么它在我录制时不读取任何数据 我尝试显示 audioData 和 fftArray 的值 但
  • Mipmap 与可绘制文件夹[重复]

    这个问题在这里已经有答案了 我正在使用 Android Studio 1 1 Preview 1 我注意到 当我创建一个新项目时 我得到以下层次结构 不同 DPI 的 Mipmap 文件夹 不再有不同 DPI 的可绘制文件夹 我应该将所有资
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • firebase :: 无法读取 null 的属性“props”

    你好 我正在尝试将react router与firebase一起使用 但它给了我这个错误 无法读取 null 的属性 props 这正是代码 我正在其中使用我的反应路由器 向下代码位于作为登录面板组件的组件上 else if this em
  • Android:无法使用 DbHelper 和 Contract 类将数据插入 SQLite

    public class Main2Activity extends AppCompatActivity private EditText editText1 editText2 editText3 editText4 private Bu
  • Android 中的处理程序与异步调用

    目前我正在使用处理程序来调用 Web 服务方法以使其在后台运行 问题是它需要更多的时间来给出响应 在性能方面似乎更昂贵 现在我计划使用异步调用 哪一个是最好的 Android 中的处理程序和异步调用有什么区别 请帮我想出一个最好的解决方案
  • 上网本上可以进行Android开发吗? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想使用我的上网本进行 Android 开发 但是当我尝试使用 Eclipse 运行 SDK 时 没有加载任何内容 上网本对于 Android 开发来
  • 没有支持 FEATURE_CAMERA_EXTERNAL 的 Android 设备

    根据this doc https source android com devices camera external usb cameras一些 Android 设备允许使用 Camera2 API 访问外部 USB 摄像头 我检查了大约
  • 错误:(23, 13) 无法解决:com.google.android.gms:play-services:11.2.0“安装存储库和同步项目”不起作用

    我正在尝试在我的 Android 应用程序中获取位置并更新到服务器 这是我的 Gradle 代码 我在这里包含了compile com google android gms play services 11 2 0 这条线是从文档中 htt
  • Dagger 2 中“HasFragmentInjector”的实际用法是什么

    我之前已经实现了 dagger2 v2 2 但现在他们也添加了 dagger android 部分 所以我正在用它创建示例项目 我知道旧的方法论 Provide and Modules and 成分等注释 但从 Dagger 2 8 开始

随机推荐