I want to be able to have different Firebase Remote Config parameter values based upon the device model.
I've set up Firebase Analytics Audiences for each device model using the "Device Model" user property (which is collected automatically Automatically collected user properties). It provides a drop down which contains the device models that have already had the app installed on, as shown in the screen shot.
Then in Remote Config, for the parameter concerned I created a "value for condition", specifying the previously created audience, as shown in the screen shot.
But having done this, the correct value for a given device model is not retrieved on the device, the device just receives the default value.
Interestingly when I create an Audience based on the user property "User ID", and use this audience to define a value for a remote config parameter it does work correctly.
Based on this I would have suspected the Device Model was not automatically collected, but the fact that device models are shown in the drop down when creating an audience appears to contradict this theory.
What am I doing wrong?
Or is there an alternative way to achieve the same goal?
Whilst it doesn't answer the question as to why using the predefined User Property "Device Model" is not working for me. One possible work-around is to define your own User Property and use this in exactly the same way to define audiences based on device model.
Of course in this case it is necessary to explicitly set the User Property on Android, e.g.
firebaseAnalytics.setUserProperty("device_model", Build.MODEL);
Where "device_model" has been created in Analytics -> User Properties.
I tested this approached and it worked fine.
Related
I'm new to app dev...
I read somewhere in the doc: "...In most cases you want to use SharedPreferences as it is automatically backed up and migrated to new devices..."
On first install my app saves a few settings with SharedPreferences. It works great but if I uninstall the app or install it on another device the preference settings are lost.
How can I have these settings saved online within google somehow to be able to retrieve them if the user changes his phone or similar...
Could someone point me in the right direction ?
I read somewhere in the doc: "...In most cases you want to use SharedPreferences as it is automatically backed up and migrated to new devices..."
Your words "backed up and migrated to new devices" is nowhere written nor its true.
We use SharedPreferences in order to minimise the database operations, its like keeping variables handy.
On first install my app saves a few settings with SharedPreferences. It works great but if I uninstall the app or install it on another device the preference settings are lost.
If you wants to store or remember the device dependent settings, use device id / imei_id and store it on your web server mysql database
Even if user uninstalls app from the device and installs again anytime in future, make a call with async task to server by sending deviceid / imei_id and fetch its settings from mysql database and show it.
How can I have these settings saved online within google somehow to be
able to retrieve them if the user changes his phone or similar...
If user changes device, you can do nothing.
One way is, keep public device_id levels keys on server.
If user changes device and uses that key, then show him a response, this key is assigned to another device, but if you are the same, wait for our support
Call him, confirm he is the same old user with new device and delete his old entry from mysql and assign old key to the new device entry
Or use OTP SMS system to identify already existing customers with unique phone numbers
If OTP authentication code is correct then fetch settings for that user from the server, delete old mysql entry, modify new entry with old key and mobile number
This should be the your direction
Edit : 2 ##
I was hoping an easier solution exist but....
There is no short cuts for developers till the date, and it will be never.
Why, no short cuts / easy ways ?
Any device ( mobile, desktop / laptop / any AI device ) which is operated by a system software, is able to perform the tasks as per it is structured.
Ex : android is java based, obviously you can Make javascript based apps, but it is the extensions to the existing system, Android still has the base of Java virtual machine. ( Dalvic / Malvic like )
So, it is always better to use native java
Yes, Kotlin is best option now a days and better than hybrid approach
Every way has its own advantages, disadvantages
If you are developer, should go with native approach
Now your java code never knows, which version it is running on, so you have to, check android versions programming wise, and decide the flow for above Marshmallow & below marshmallow too, and it is explicitly done by developer by coding.
Ex, once user registers, he never shown please register again screen, it is not the magic, nor google, nor, java, nor android does anything, developer has decided, planned, architectured, designed, coded, tested that.
Even developers needs to take care of exceptions, you need to handle it in order to save your app from crashing.
In short developer is god, who creates his own universe, and everything is pre-planned and verified thats it.
You should use allowBackup = "true" in your manifest file. More details can be found here: AutoBackup
I am trying to create an experiment using Firebase remote config.
The criteria is as follows:
It should target only new users who have not used the app ( opening the app for the first time)
Now on further research I found that there is a user property as below:
However, this is not available in the experiment window or a similar property that fulfils the above criteria in the Firebase console as seen below:
I can only see the user properties set by my code. One way I can think of is to use one of my custom user property which is not yet set (but set to a value like null), but I don't know how I can do this.
References
https://support.google.com/firebase/answer/6317486?hl=en
https://firebase.googleblog.com/2016/10/better-user-targeting-with-firebase.html
I will share our experience with experiments for new users and how the different combinations of targeting work because we worked with it a lot already. You can skip the investigation part if you're not interested and just check the solution that we use now.
Our Investigations Part:
Firstly, when we integrated Firebase, we were afraid that Audiences won't work properly for experiments targeting cuz all current users will be treated as new ones after integration, so we checked several approaches and went with an approach of creating specific User Properties that we specified on the client side differently for old/new users. For instance, we created a User Property called adv_experiment_enrolled and specified on client side values 'enrolled'/'not_enrolled', so all new users after installation of this version became 'enrolled' and old ones after updating the version just became 'not_enrolled'. And we just used that User Property as targeting in an experiment. That worked well, but it wasn't a general approach that we could use easily for all experiments and we needed to create User Properties for each new experiment.
So we've tried the Audiences approach after few months of integration that was what #jackes described here with First Open Time user property:
https://stackoverflow.com/a/50075684/2723437
And we've got several problems, first of all, seems they had some troubles with populating of that kind of audience and just ~3-5% of new users were getting there. We also created an Audience depending on First Open event itself and used it too, it was populating better and was close to the real number of installs that we had. But we've noticed problems with this approach as well and the biggest one was that an experiment had only 20-30% of users from that Audience. We tested it and noticed by some of our metrics that seems users are not enrolled in this experiment in their first session cuz 1) Firebase takes some time to enroll a user in the Audience and 2) Remote Config has 12h cache by default, so it wasn't really a data for most of the new installations.
A solution that seems to work well for now:
We were surprised with that Firebase does have User Property for First Open Time, but doesn't allow to use this as the targeting for experiments (It would be very helpful to solve this problem tbh), so we just decided to try our good experience with User Property targeting and apply the general approach First Open Time user property, so we've created our own custom_first_open_time especially to target installations after some specific time (we just used current timestamps for platforms in seconds).
Important notes:
- You have to set up user properties before loading a remote config.
- You have to keep this first open time on the client side persistently once you generated it (usually you use NSUserDefaults/SharedPreferences for iOS/Android for that)
Sample of experiment configuration:
Didn't tried, but it should work. Create an Audience in Firebase Console with following condition: First Open Time is greater than or equal to some date. Where the date should be the next day after you starting an experiment.
I am creating one Google Fit compatible App. My objective is to store Google Fit data using HistoryApi, and provide kind of Back Up- Restore functionality to user. If user buys new Android devices then he/she should be able to BackUp(sync) old data using his/her account.
I need to use Custom Data Type, as Public Data Types doesn't meet my requirements.
Everything works perfect, I am able to insert data and read data using History Api.
But When I try to read data from Another Android device using same Google Account then data is not available to read there.
My problem seems similar to this Custom DataTypes not synching between devices
This statement from Google Fit Document is not clear to me.
Custom data types are not available to use in other apps. Only the app
that creates a custom fitness data type can use it
source : CustomDataType
Q-1) What does it really means ? If I have an app GoogleFitDemo installed on multiple Android devices, then is it possible to sync data between this same app between multiple Android devices ?
Q-2)Is it improper way to store and backup data using Google fit ?
Update:
Finally, I found that Custom Data Type can also be synced normally, same as other Public Data Types. I had the sync issue as mentioned by #Ifor. Sync functionality is still buggy. In some scenarios sync stops working, and sometimes synced data is inconsistent across multiple devices.
1). My understanding is that same app same account but different devices it should work. Having said that sync is notoriously slow (hours days...) and has been buggy so it may be hard to tell if you have it right or not.
2) There are better backup methods... But if the data fits in with the rest of the stuff Google Fit is about and is not too big then it's probably ok.
I require the list of fixed properties of android.os.Build class. I've obtained the list from here I bold those that I know are fixed. By fix I mean no change by firmware update, reset factory, ...
android.os.Build.VERSION.RELEASE //The current development
codename, or the string "REL" if this is a release build.
android.os.Build.BOARD //The name of the underlying board, like "goldfish".
android.os.Build.BOOTLOADER // The system bootloader
version number.
android.os.Build.BRAND //The brand (e.g., carrier) the software is customized for, if any.
android.os.Build.CPU_ABI //The name of the instruction set (CPU type + ABI convention) of native code.
android.os.Build.CPU_ABI2 // The name of the second instruction set (CPU type + ABI convention) of native code.
android.os.Build.DEVICE // The name of the industrial design.
android.os.Build.DISPLAY //A build ID string meant for displaying to the user
android.os.Build.FINGERPRINT //A string that uniquely
identifies this build.
android.os.Build.HARDWARE //The name of the hardware (from the kernel command line or /proc).
android.os.Build.HOST
android.os.Build.ID //Either a changelist number,
or a label like "M4-rc20".
android.os.Build.MANUFACTURER //The manufacturer of the product/hardware.
android.os.Build.MODEL //The end-user-visible name for the end product.
android.os.Build.PRODUCT //The name of the overall product.
android.os.Build.TAGS //Comma-separated tags
describing the build, like "unsigned,debug".
android.os.Build.TYPE //The type of build, like
"user" or "eng".
android.os.Build.USER
Please help me complete the list
If you look at the source code to Build, you will see that all of these values -- including those you have in bold -- come from system properties files. Hence, any of these values can be modified by ROM modders or the original device manufacturer as they see fit.
I'm not going to address the woes with consistencies of Build as Mark has illustrated why there isn't a guaranteed answer. Instead I want to respond to what your purpose and intent is.
If I understand correctly, you are trying to uniquely identify a single device. I point you firstly to this answer, from which you can simply conclude that a generic solution is not possible. Either resetting factory defaults or switching SIM cards (if the device has one) will change any sort of unique ID and fool your app into thinking it's a different user.
You need to rethink what you're trying to accomplish. Why do you need to uniquely identify a device? If you're trying to identify a user, then this mindset doesn't cope for multiple devices either. This is now especially the case with Jellybean 4.2, where a device may support multiple users. See also this insightful blog post on the Android Developers Blog.
Can you have the user attach his Google account? Or account for your own service? If you can identify a user, it is then trivial to identify individual devices through UUID.randomUUID().
If I understand correctly (regarding your follow-up comment) you want to identify a device without integrating some kind of registration or login mechanism.
Instead of implementing yout own ID computation algorithm I would suggest using an OpenUDID implementation for android (see https://github.com/vieux/OpenUDID).
I'm using Google Analytics SDK to collect statistics from my Android application. I want to be able to create a chart showing which language are users using.
To do so, I'm creating a visitor scope custom variable like this:
tracker.setCustomVar(1, "Language", language, 1);
The problem is I'm afraid that this approach isn't correct. I want to create a pie chart in Home -> Dashboards in google analytics, so I choose Add widget -> Pie -> "Unique Visitors" grouped by "Custom Variable (Value 01)".
Pie chart created like above shows invalid results. The goal is to get last variable value for each user and then display the number of users for each value. What it actually does is it takes all variable values and for each value it shows the number of visitors that ever had this value.
This means that if someone switched between languages, he will appear in both languages in the chart. Not the one that he is actually using.
So my question is - how to do it correctly? Should I change something in the code, perhaps use something other than variables? Or maybe it's possible to fix it just via google analytics website?
Thanks
There's no way to achieve what you want.
If the same visitor changes it's language it will have that language from now on, but he'll still show up as the old value on the days before. It happens because in GA history is never rewritten, data is processed by session(visit) and the data that goes in is static and can't be removed or changed. If the visitor was reported only on the new value it means that the visits before would have been changed. This is just against the design.
You may find other ways to remedy that and understand better people that are changing their languages on the application. You may fire an event when Language is changed for example and understand the impact of new languages being added to your application.
There's only one place in GA where you have a better view on multiple sessions. and that's the multichannel funnels, but they only work for Goal Completions reporting on different Traffic Sources. The reports you see there are processed by a separate system inside Google Analytics and can break some of the rules about how Google Analytics processes and stores data. Because of that they can tie the visit back together and understand the progression of changes that happend on the traffic sources dimension and lead to a goal completion.
I'm sorry it doesn't solve your problem. But unfortunately it's just not possible by design.
You don't need to set the user's language yourself, go to your Google Analytics webpage > Audience > Demographics > Language.
This will show you everything you need to know about your users' selected languages.
EDIT:
For a custom app value (like a setting value), in my experience the best approach is to set up a daily/weekly ping of that value as an event, so you'll get a daily pie chart of all your active users selected language.
you can set up such a ping using the AlarmManager