I have a calendar tool that integrates with Outlook Calendar. To respond to changes on the Outlook side, I subscribe to push notifications. If I miss the first notification of a change, Outlook sends others with ChangeType: 'Missed' and I synchronize with the user's calendar to retrieve the details of the change. However, deleted events do not seem to be included in the sync response.
The documentation suggests that it is possible to get deleted events:
Synchronize and get new, updated, or deleted events in a specified time range from the user's primary calendar (../me/calendarview) or from a different calendar.
There is even a section about deleted events and synchronization.
Deleted events will contain a reason property with the value of "deleted" to indicate a deleted entity. If the event is a recurring master event, you should delete all of the occurrences and exceptions.
'Created' and 'Updated' ChangeTypes work fine.
Am I subscribing incorrectly? Or is this not a feature of the Outlook Calendar API?
Here is the body of my subscription request:
{
'#odata.type': '#Microsoft.OutlookServices.PushSubscription',
'Resource': "https://outlook.office.com/api/v2.0/me/calendars/#{calendar_id}/events",
'NotificationURL': MY_URL,
'ChangeType': 'Created, Updated, Deleted',
'ClientState': 'foo',
'SubscriptionExpirationDateTime': TTL.minutes.from_now.iso8601
}
Related
=====================
I thought about it for a while and proposed a potential solution at the end of the question, do you think it's feasible?
=====================
I'm using Firebase Realtime Database to support chatting in my iOS app. I have a node called "conversations" in database, which is structured like so:
-conversations
-user_id_1 // This is you
-recipient_id_1 // id of the user who's chatting with you
-message_id_1
-message: <some_message>
-date: <some_date>
-message_id_2
-message: <some_message>
-date: <some_date>
-recipient_id_2
-message_id_1
-message: <some_message>
-date: <some_date>
-message_id_2
-message: <some_message>
-date: <some_date>
Whenever a new message is sent to a user, he should get a notification.
I have thought about using Push Notification, i.e. I use Cloud Function Trigger to observe the path:
functions.database.ref('conversations/{uid}/{recipientId}/{messageId}').onCreate((snapshot) => {
// Send push notification to user with "uid"
})
However, there's a problem with this, what if the user blocks the push notification of the app? The user is not gonna receive any message while he's not using the app (which is what he wants by turning off push notification), but he's not gonna get any message even when he's in the app. Therefore, I'm thinking, maybe I should use Firebase SDK in my app to observe database like so:
Database
.database().reference()
.child("conversations").child(<my_user_id>)
.observe(.childAdded) { (snapshot) in
// do stuff with snapshot
}
But then, this only observes newly started conversations, i.e. if the user already had a conversation with, say "person1", and "person1" sends a new message to the user, this observer wouldn't be triggered. Then, I was thinking:
Firstly, Keep the above observer so that I get notified when a new conversation is started
Secondly, Create multiple other observers that listen to my existing conversations:
Database
.database().reference()
.child("conversations").child(<my_user_id>).child(<existing_recipient_id>)
.observe(.childAdded) { (snapshot) in
// do stuff with snapshot
}
But this way, how do I know all my "existing_recipient_id"? I certainly shouldn't fetch them on start up:
Database
.database().reference()
.child("conversations").child(<my_user_id>)
.observeSingleEvent(of: .value) { (snapshot) in
// Extract all "existing_recipient_id"
}
Because this fetches all my conversations and their messages, which could potentially be multi-GBs.
I have the following 2 questions:
If I have 1,000 conversations with 1,000 people, should I have 1,000 observers in-app? If this wouldn't cause any problem, say performance issue, how do I set up these observers so that I could avoid the problems above?
I'm definitely using push notification, in case user is not in the app while a new message is sent to him. But, I don't know whether the user is in app or not, if he is, I already have those observers, push notification seems redundant, and it raises the cost. Is there a way that I can avoid this?
Temp solution
Write a cloud function that fetches all "existing_recipient_id", which is just an array of strings.
In the app, I add a listener that monitors the device's connection state, whenever the device comes back online from offline, also when the app first launches, I call that cloud function to fetch id's of all existing conversations.
Add observers to each of those conversations
Add observer to listen to new conversation
But I still don't know what to do about push notification when user is in-app, I guess I'll do it even though it's redundant
I'm trying to implement local notifications to my app. They will function as a reminder for an event, but the notifications must come from my app, and not from Calendar or Reminders.
My question is, how can I create notificaitons that fire before a certain date, while showing the actual date in the 'time-field'?
This is what the Calendar can do:
Notice the top right corner saying "in 5m".
I'm trying to get the same functionality for my own notifications, but I can't find anything about it. This is the only thing I can get:
As soon as the notification arrives, it says "Now", and then proceeds to count up the amount of minutes ago. I need it to be sent X minutes before, and count down to "Now", then count up. Is this possible?
How about you create multiple custom Notification.Name like this posting. You could have .onTime, .fiveMinutesReminder, .tenMinutesReminder, and so on. The logic in your app would set when to fire those reminders. Your selector handler function would need to have some kind of switch statement to handler different reminder. The handler will need to show different text message based on the kind of the reminder.
I'm using Firebase Messaging to send out notifications to users of my iPhone app. My database is structured like this:
- Users
- user1
- user2
- Groups
- group1
- members
- user1
- user2
When a user joins a group they get subscribed to a topic corresponding to that group. I have a cloud function that listens for writes in that group, and sends a notification to the groups topic when a write happens:
exports.sendNotifs = functions.database
.ref('pets/{petId}/events/{eventId}').onWrite(event => {
const pet_Id = event.params.petId;
const payload = {
'notification': {
'title': `${toTitleCase(name)} just logged an event`,
'body': `${events[eventType]} for ${toTitleCase(petName)}`,
'sound': 'default',
}
};
admin.messaging().sendToTopic(pet_Id, payload);
});
However, this results in everybody getting a notification including the person who did the write that triggered the notification. I only want other people in the group to display a notification since the triggering user doesn't need to see one. I tried appending the sending user's uid as extra data of the notification and only displaying the notification if the recieving user's uid doesn't match the notification data's uid. This works when the application is in the foreground but not if its in the background, so if the user writes then closes the application before he receives the notification it'll display for him when he receives it, something I'm trying to avoid.
How can I make sure only other members of a group get a notification? Are messaging topics not good for this?
If you use Topics it's not possible to send to everyone except one.
If you are Ok sending to everyone, and then filtering on the client, you will need to use the data messages, and not notification messages, to avoid the problem with background/foreground you described.
https://firebase.google.com/docs/cloud-messaging/concept-options
i guess that the solution is:
each iOS client from group1 will subscribe to topic /topics/group1.selfUserId
the server already have the list with all users that are part of group1
the iOS client ask server to send notification to group1.members beside selfUserId (make a http post request)
server send gets all group1.members beside selfUserId and send notification to all /topics/group1.memberX
As already mentioned, you cannot exclude someone who has been registered to a Topic.
So what you can do is sending a message to a single device. So for example you have a group of ten persons, one person posts a message, you have to send nine single messages to the other nine persons of the group.
What you need to do is to store the registration token of every single user into your database and you have to take into account that registration tokens will change after some time.
I have a coaching app that has a section where I can push realtime updates out to the players like: "No Practice - Do to inclement weather, practice will be pushed until Friday"
I have been trying to figure out how to send automatic notifications when I update this UpdatesTableView with a new post. Like "New Update Posted".
I post my updates to the Firebase Database. There must be a way to listen for changes and when there is to push a notification out to all the users?
I already have firebase notifications set up in my app but I have to utilize the Firebase console to push these notifications every time i push an update. Does anyone know how to automate this? Thanks!
You can easily do that by listening/Observing to any data change at a particular location in firebase. If new child is added to that path, associated block will be called.
In your case, you can observe UpdatesTableView. and whenever you post any update, call the block which will send notification to all users.
If you are using Swift:
func observe(_ eventType: FIRDataEventType, with block: #escaping (FIRDataSnapshot) -> Void) -> UInt
If you are using Objective C:
- (FIRDatabaseHandle)
observeEventType:(FIRDataEventType)eventType
withBlock:(nonnull void (^)(FIRDataSnapshot *_Nonnull))block;
According to official firebase documentation :
observeEventType:withBlock: is used to listen for data changes at a particular location. This is the primary way to read data from the
Firebase Database. Your block will be triggered for the initial data
and again whenever the data changes.
And, Whenever you would like to stop listening to data changes, you can Use removeObserverWithHandle
Use removeObserverWithHandle: to stop receiving updates. - parameter:
eventType The type of event to listen for. - parameter: block The
block that should be called with initial data and updates. It is
passed the data as a FIRDataSnapshot. - returns: A handle used to
unregister this block later using removeObserverWithHandle:
For more and detailed information, Read iOS firebase#Attaching Observers to read data Documentation.
Also, For sending Notifications to users effieciently, you can use Firebase Notification. Have a look at it. i dont know about your usecase properly, But i think this will help.
I also stucked with same problem where I wanted to show notification to users whenever data changes in Firebase irrespective of application in foreground or background.
I achieved it by binding ChildEventListener with a service which keeps running in background. At every childAdded event data is stored in sqlited db and a new notification object is created and shown to user.
I'm using Realm in iOS, I have user table and history table.When user table's record is updated or created,I want to create a trigger to save this event in history table.
Check out the Notifications section of Realm documentation. You should use a notification token to listen changes made to your User table and then run the code that saves the event to History table in the notificationBlock of the token.