How to send FCM based on user's location - firebase

I built a shopping app using React Native. We have a lot of stores and restaurantes from all over the country registered on our app.
We send messages to our users using FCM when a specific store publishes a new offer, based on user interest and the publisher. If a restaurant posted an offer, we will send to all users registered on the topic "/restaurants". This behavior is bad because maybe the restaurant is too far away from the user, and this offer isn't important to him.
That's why I want to create topics based on a location, so if a restaurant from Chicago posts an offer, I would send just to users registered on "/restaurants/chicago".
Is this the best way to do it? Do firebase offer something similar out-of-box? And how would I keep track of users to know when they go from another city from another?

TL;DR: Text in Bold.
It is possible to create a background service that will (once an hour) get the device location. https://developer.android.com/about/versions/oreo/background-location-limits
Best way to get user GPS location in background in Android
Don't add location background service if you can get away with not having one. It drains the battery.
You should decouple the location from the FCM and use a little bit of prediction. Send a notification when they would start planning to visit the restaurant and resolve their location/group when they open your app.
I assume your app has location permissions enabled. What you should do for your user is store a list of their past locations in the Firebase Database (or the Cloud FireStore). Resolve these locations to a metropolitan area, zipcode, etc. Keep a counter to help weight this location (and to sort)
You should also store a list of restaurants they viewed from a map view...specifically their locations. What you are going to do is compute an approximate distance from a central location and create an average travel time.
E.g. I prefer to eat in a sub metropolitan area that is (on average) 30 minutes from where I live. I also like to eat around 6pm. I need to make a decision about where I want to eat around 5:15pm.
You should also keep track of what times they viewed your app for restaurants in the database To figure out when they start making decisions to eat.
Another concern is the day of the week. For instance, because I live 30 minutes from good places to eat, I will sometimes eat locally. These local places will be packed on certain days of the week.. Thursday they will be packed, Friday will be 1/2 of that, and Saturday is next to nothing. Then Sunday/Monday they pick back up to Friday levels. This is because people are more willing to drive to town on Friday/Saturday night, but they don't want to cook and will eat out on Thursday locally.
Now is when you start using Predictions. Firebase has a Predictions module, and/or you can write Cloud Functions to organize your database and schedule FCM.
First, you need to collect data. One method is to kick off a location service from an hour when they open your app. Hopefully, this will catch your user at which location they chose to eat at (we'll call this the Label, for analytics this will probably be a conversion event). The other trick is to kick off a notification in an hour to rate their dining experience. This doesn't require location background service, and if they open the notification, you can grab their location then.
Having in-App Coupons that the user can present at the restaurant can allow you to grab location.
Also, learn which days of the week they prefer to eat out and which areas they target on those specific days.
If the user is in a different metropolitan area, then waiting until they open the app will allow you to display relevant subscriptions. I flew to Seattle and was starving at 4pm.
Given as many data points (features) as possible (day of week, time of day, day of month, day of 2 weeks, average distance to local restaurants, average distance to metro-restaurants, is_holiday, average_notification_open, average_time_at_restaurant) And data labels (Eat_locally, eat_metro, Eat_home) you should be able to start classifying users into different groups.
So, 1 hour before your user's average eating time, you should perform some server side calculations to determine where your user is likely to eat. For example, if they eat_locally on Thursday night, you should schedule FCM according to the average distance of local restaurants.
Never funnel a specific user to a specific restaurant. Comply with GDPR even if you don't operate in the EU (it covers their citizens). Be transparent with your data collection policy and always try to anonymize/randomize.

Related

Making a leaderboard with Firebase Realtime database and Unity

I am making a leaderboard by using firebase realtime database, unity and facebook ( for profile pic and name )
But I am struggling, I am not sure about the way of doing that. I want to display multiple leaderboards -> All time WORLD / REGION / FRIENDS score, monthly WORLD / REGION / FRIENDS and weekly one.
I know I can use cloud functions to reset weekly and monthly leaderboards.
But how can I store world and region scores ?
Now I just have this ->
https://cdn.discordapp.com/attachments/440873502535450627/821361474353889320/ld.JPG
Thanks to that, I can easily get region leaderboards getref.getchild users . getchild france and then orderbyvalue . limittolast ! this is good !
The problem is how could I get world leaderboard ? ( I have other countries ) I am so lost...Do I need to make another structure for my leaderboard ?
There are a number of considerations that you might put into this including pricing, how much you trust the client, &c. Generally, with a NoSQL database like Realtime Database, you might have a lot of redundant data to make up for the fact that your ability to query is limited. It's also really easy to pull in a lot of data by mistake, so you'll see a number of best practices around keeping your database shallow.
With that said, I think I might recommend reorganizing your data a little bit. For example:
Have one node named "users" with all of your users in there. Each "user" in users should be placed in a node that's simply the userid (which makes security rules easier to write), and here you can place the all time score, monthly score, and weekly score. I'd also recommend storing the time you got that score (using ServerValue.Timestamp) so you don't have to worry about going through your users and deleting all the old scores. If your weekly timestamp isn't this week, you know to ignore/overwrite it (obviously, time is hard, so you'll have to work out what a "week" means to players of your game wrt time zones &c).
I'd also put an array of all a user's "friends" under this user node by their user id. That way, when you go to look up friends, you just just ask for "users/" explicitly there.
Now for regional and world leaderboards on monthly and weekly cadences, I'd just copy everything you want to display into that leaderboard node (say username and score) and add the uid if you need to attribute it back to a user (say if you want to click on that score and see their all time record). So if a user lives in France and they get a weekly high score for them, I'd first write that user's "users/" node with the weekly score and timestamp, then I'd go out to the weekly leaderboard for France and add the new score if it qualifies (ie: don't add it if you're only tracking the top 10), then go out to the world leaderboard and add it there.
How you do this copying is up to you. You could make it the client's responsibility with security rules just making sure they're well behaved - which would probably be fast and cheap but might get weird if they go offline partway through updating. You could use a Firebase trigger that would listen for a user updating their node and copy the data out to the respective leaderboards (this would be more expensive since you're paying for Cloud Functions time and a bit slower but will always work once the user node is updated).
A final note is that for, say, weekly leaderboards. I'd have a node that says "this is France's weekly leaderboard right now" and have all clients read that first before figuring out where to write. That way, at a time you decide for when the week turns over, you can change that node and just have people start writing somewhere else. You can then keep the old leaderboard up for some time (ex: maybe you want to see who changed between this week and last), and you can delete it at your leisure after you're sure that all players have their score in (ex: over slow internets, disconnects, &c).

Tracking a Search that leads to a sale in GA

This seems really basic but i am struggling with it
We have a client who runs a travel website.
They have a few different search bars eg Flights, Hotels, Carhire.
I am trying to track the performance of each... "What % of people completed a sale that ran a Flight search." Same for Hotel, and for Car hire
Any ideas for the best way to get this info in GA?
Many thanks
There are a few ways to get this information, each with their pros and cons. The options that I see immediately available are segments and goals.
Segments are great because they are retrospective and generally more flexible, with the ability to be changed if you find your criteria isn't quite right. You create here, and specify sessions that go through search results pages etc:
Then you can create another segment for booking confirmation page, and any other intermediary steps that you'd like to report on. The main con of segments is that you can only pull in 4 at a time, but if you have more you can pull them 4 at a time and copy+paste the data into an excel sheet or google sheet. Segments can also be pulled via the Core Reporting Api and DataStudio which makes them great for automating into dashboards.
Goals are cool because they pull into the default reports, and basically track sessions through a particular page, event or sequence. The main con I see and the reason is that I don't use them is that they only start tracking fro mthe time you create them , and if you change the configuration it does not impact historical data, so your data can get messed up quickly if you don't have sandbox GA views or sandbox goals for your testing before putting it into a dedicated goal slot. You can also only have 10 or 20 goals depending on your plan, so once data is tracked against that goal you can't remove or clear it.

Tracking events and making sense of it

Lets say I wish to track
User action - game he played - which area he stays - his house number.
If I were to track these event actions in Tabular format, it would look like:
UserId|Game|Area|House|Timestamp so on.
Then I can always run SQL queries if I want to answer few business queries. Like
1. In a given day/week, who is the most active User
2. Which game is most-played?
3. Which area plays most events
4. Which user from which area are the most active
Whats the best way to capture this using Google analytics? Will custom dimensions be useful. Or GA is not suitable for this kind of insight?
Thanks.
First of all, the house number is too precise, it would be against GA's ToS.
In GA everything is captured in "hits", you can think of this as one "row" of data.
Let's look at what you wanted to find out:
Most Active User? - This depends on how you determine "Active". Is it the longest Session durations? Tried most games? Most logins? Most sessions? To track a user, you'd need a User ID tracked.
Which game is played the most? - Again, what is played the most? Longest time in game? Most "start" games? This would require you to know the Game that was played and when someone started playing
Which area is most active? -This would go back to the definition of active, the region information is needed along with the active definition
Which users are most active in an area? Same as above, the user would need to be identified and area
To determine which Custom Dimensions (CDs) you want, let's look at the example data points you want to track and try to determine the scope and if it already exists as a standard dimension:
User ID - this is obviously related to the user, makes sense to be user-scoped
Game - This is a tougher CD. I would think that in a single session, users can play multiple games, thus I'd think you'd want this to be hit-scoped.
Area - GA already provides this based on the ISP
Timestamp - GA already provides time dimensions
From above, we can determine that you need to create two CDs, one to track User ID, the other to track the Game.
You can also look into using the userid feature in GA for cross-device tracking.

How to differentiate active users from non active ones

I built an app and I would like to differentiate the behaviours of my users regarding their activity levels.
Objectives : make monthly users become daily users by understanding how daily users use the app vs monthly users and trying to narrow the gap between them.
I am well aware of the Daily / Weekly / Monthly active users Firebase offer but it is still a snapshot at a specific time.
Basically, if someone open a session at least one time during 20 days / month => highly active users, if someone opens it at between 7-20 times a month => medium active user, if someone opens it less than 7 times => low active users.
Do you have any clue on how to split these to then understand their behaviour?
because you are tagging your question firebase database that means you want to do it programmatically.
you can make a field in user node name it counter and every time the user login to the app you just increment the counter and make a query to bring the count that's it.

How to handle time zone for stores located in diff time zone

I have web application which controls the stores locate din different time zones.
In this web application user will set rules that, any particular product is in discount for any given period of time i.e. 1-Aug 2014 to 5-Aug-2014. so how can this rule be executed in web application. this info can be inserted from anytime zone. but store in Europe and Store in US should have to make this product available from exact 1-Aug-2014, Europe will be early compare to US.
SO how we can handle this kind of scenarios.
In general:
Store the time zone for each store, such as America/Los_Angeles or Europe/London.
When checking for discounts, get the current UTC time and use the store's time zone to determine the appropriate local time.
Compare that local time against the expiration date for the discount.
This assumes that the business rule is to rely upon the store location's time zone. This might not necessarily be the case - as many online stores serve customers worldwide without regard to where the physical store or product is located. In that case, you need to determine who's time zone is applicable. Is it a single fixed time zone for the whole company? Or perhaps it's aligned the end-user's time zone, such that those in different time zones would have the offer expire at different times. You'll need to decide what is appropriate for your particular business.
Sorry I can't be more specific, but you didn't provide many details to go on. If you need further assistance, please consider editing your question to include details such as what language and platform you're using, what code you have tried, and what the specific business rules are.

Resources