Best way to handle both user authentication and in-app purchases

1,081 views
Skip to first unread message

Andreas Bartels

unread,
Mar 15, 2017, 10:19:13 AM3/15/17
to Firebase Google Group
I've run into a roadblock thinking about certain app functionality:
  1. I want to be able to restrict certain functionality, for example write access to the Firebase Realtime database, to users that are authenticated.
  2. I want to be able to restrict certain other functionality, for example read access to part of the data that is written by users, to users that are paying customers via in-app purchases. In the best case, this would include not only one-time payments but also a subscription model.
It is easy enough to implement both of these individually, but I'm not sure how to best handle them in combination - for example when a user reads (case 2) data and then reacts (case 1) to it by upvoting, placing a comment or whatever.

I've thought about storing information about an in-app purchases in a $user-id branch of Firebase, but then I would no longer be able to rely on Play Services functionality to detect directly whether I should make some function available to a user. Alternatively, if I keep this check, how can I make sure that the app of a paying customer isn't used to log in to different user accounts (including those of non-paying customers) to temporarily gain certain functionality for all those accounts?

I guess what I'm asking is if there's a proper way to connect the list of my users (Firebase authentications) and my customers (in-app purchases), or if I need to implement around it, for example by using consumable purchases instead?

Kato Richardson

unread,
Mar 15, 2017, 1:48:45 PM3/15/17
to Firebase Google Group
Hi Andreas,

The two options available here are to sign your own tokens, and add whatever sort of play store data you want into them, or to write meta data about in app purchase into your DB as you suggested above. Both should accomplish what you want, and the security rules should play rather nicely together--I can't see how both together make this a problem without a minimal repro demonstrating the rules, sample data, code, and the problem you're experiencing.

Alternatively, if I keep this check, how can I make sure that the app of a paying customer isn't used to log in to different user accounts (including those of non-paying customers) to temporarily gain certain functionality for all those accounts?

Not really sure what this means. If a user logs into a different account, would they not then have different auth credentials?

☼, Kato

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-talk+unsubscribe@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/18dc4492-d770-4d64-83e2-a17cecf9f438%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Kato Richardson | Developer Programs Eng | kato...@google.com | 775-235-8398

Andreas Bartels

unread,
Mar 15, 2017, 5:41:31 PM3/15/17
to Firebase Google Group
Thanks Kato,

I'm afraid there's not enough implemented to give an actual code/rules/data example yet, but perhaps the following helps understand where I see a problem:

Consider an app that allows all authenticated users to "post" something (while, for example storing their location or some other property of the post), but only users that have paid for it to "view" and "reply to" all posts matching a certain filter (say, all posts that have been made in a certain location).

I can check what posts a user should be able to view by doing something along the lines of

Bundle purchasedFilters = mService.getPurchases(...); //using Google Play's In-app Billing API
//show posts based on the filters the user paid for

Then, when the user replies to one of the posts shown, I do something along the lines of

FirebaseUser user = firebaseAuth.getCurrentUser(); //using Firebase Auth
//get userID, username etc. to build the reply data and store it with Firebase

The problem is that the first piece of code checks against the device account (the user's Google account, which they used to buy the app or in-app products), while the latter checks against the auth credentials the user happens to use with my app (which can be a Google account, but also Facebook or just password/mail - in any case different from the device account).

If I do just that, then non-paying user B could use the app installation of paying user A, log in with his own credentials (which are independent from the device account), and use functionality that he hasn't paid for himself.

If I use consumable in-app products, I can make sure that information about all purchased products are transferred to my database immediately, but in that case I think I can't make use of the subscription model Google Play offers.

Kato Richardson

unread,
Mar 15, 2017, 6:35:43 PM3/15/17
to Firebase Google Group
It sounds like you'll want the custom tokens solution then. You can roll the device account ids in as your unique identifiers and either store purchase information in the db or directly in the tokens.

☼, Kato

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-talk+unsubscribe@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Amit Mohan

unread,
May 15, 2020, 11:42:55 AM5/15/20
to Firebase Google Group
Hi Andreas B,

Have you implemented any solution to this problem? Actually, I am also facing the same issue, and I am puzzled right now thinking how should I save the purchases data onto Firestore database without facing the issue that you specified, where any non-paying user can gain access to paid features.

Hope to hear from you soon.

Thanks!

Kato Richardson

unread,
May 15, 2020, 12:07:32 PM5/15/20
to Firebase Google Group
Hi Andreas,

When a user makes an IAP (in app purchase), store that in your realtime database in a private profile (e.g. /users/private/<user id>/isPayingCustomer = true).

Then security rules would look like so: ".read": "<document owner id> === auth.uid && root.child("/users/private/" + auth.uid + "/isPayingCustomer").val() === true"

Alternately, you could use custom claims for this as well.

☼, Kato

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/bcbb2d71-bddc-4ffa-bc15-d6d18cef7417%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages