How can I determine a user_id based on an email address in App Engine?
Asked Answered
T

2

13

The newest App Engine SDK (1.2.1) has an API call to compute an ID for a user account based on his email address. (The ID remains the same even if the user changes his address later.) See this question about unique, opaque user IDs for information. However, I have a problem with this API call.

user_id() works for logged-in users (i.e. from users.get_current_user), but it returns None for objects created by the users.User() constructor.** What gives?

For example, using the excellent App Engine Console, this code does not work.

>>> import google.appengine.api.users
>>> me = google.appengine.api.users.get_current_user()
>>> me
users.User(email='[email protected]',_user_id='105261964646342707921')
>>> me.user_id()
'105261964646342707921'
>>> somebody = google.appengine.api.users.User('[email protected]')
>>> somebody
users.User(email='[email protected]')
>>>somebody.user_id()
>>> type(somebody.user_id())
<type 'NoneType'>

I want a simple way to convert an email address to a user ID. How can I coerce this ID from Google ahead of time; or if it's not possible, why not?

Edit: Here is the current workaround.

Thanks to Nick Johnson for his answer. Here is his solution in action:

>>> from google.appengine.ext import db
>>> from google.appengine.api import users
>>> class User(db.Model):
...   user = db.UserProperty(required=True)
...
>>> def email_to_userid(address):
...   """Return a stable user_id string based on an email address, or None if
...   the address is not a valid/existing google account."""
...   u = users.User(address)
...   key = User(user=u).put()
...   obj = User.get(key)
...   return obj.user.user_id()
>>> email_to_userid('[email protected]')
u'105261964646342707921'
>>> email_to_userid('this@is-an-invalid-email-address')
>>> email_to_userid('this@is-an-invalid-email-address') is None
True
Thompson answered 3/5, 2009 at 5:2 Comment(6)
You might want to add the caveat that if there is no Google account for the given email address, no user ID will be returned.Loma
Shouldn't you delete the entity at the end of the process?Rives
This doesn't work for me. Maybe it doesn't work with ndb?Rives
I confirmed that this works with db, but not with ndb.Florrieflorry
It probably doesn't work for ndb because the ndb object gets cached in memcache, so the object you .get doesn't come from the datastore.Subspecies
Does anyone here know how to get the user_id with NDB? I've been stuck on this for a while.Collegium
L
21

The current workaround is to create a User object, store it to the datastore, and fetch it again. If the email corresponds to a valid Google account, the User object in the returned entity will have its user_id field populated.

Loma answered 3/5, 2009 at 11:2 Comment(6)
Thanks. I am testing this right now and if it works, I'll upvote and accept your answer.Thompson
+1, It works. I will put some example code in the edited question, so hopefully this question can become the canonical answer for how to convert an email address to a user ID.Thompson
Same thing i want to DO For Android. . . Is Anybudy help me Please. . . Thanks in Advance. . .Renfrew
Hi Nick, I'm confused, apologies if I'm being dumb. Are you saying with the above workaround that it provides a way of programmatically testing whether the supplied email address is associated with a valid Gmail account - coz that is my legitimate use case. However, first of all I can't get it work using Java. Secondly it seems to contradict this answer, which implies exactly this sort of test is deliberately not supported:#13314377Meier
okay, got it working now, so I guess it is possible. thanks!Meier
Does anyone have a code snippet for doing this in Java?Widely
C
1

To make the proposed solution work with NDB, just add use_cache=False, use_memcache=False to the get method. That is: obj = key.get(use_cache=False, use_memcache=False) This guarantees getting the entity from the Datastore with the user_id param populated (only if this is a valid Google account).

Canalize answered 5/12, 2016 at 0:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.