Facebook, su SDK y el email sin confirmar

Como sabréis si alguna vez habéis desarrollado una aplicación que requiera login (ya sea de escritorio, móvil o web-app), la autenticación del usuario es una de las cosas que más dolores de cabeza puede provocar. ¿Obligo al usuario a darme equis dato? ¿Cómo lo identifico de manera única? ¿Cómo almaceno en la base de datos toda su información de manera segura? Gracias a $root, en los últimos años han surgido servicios de autenticación ofrecidos por grandes redes sociales que permiten usarlos a ellos como intermediarios en este proceso.

login-facebook-button

Es decir, confiamos en que el usuario A es realmente A porque un tercero, C, garantiza a nuestro servicio, B, que A es quien dice ser. De esta manera eliminamos de nuestra responsabilidad gran parte de la gestión segura de usuarios (no toda) y nos despreocupamos. Enseñamos a nuestros usuarios botones tales como “Login with Google+”, “Login with Twitter” o “Login with Facebook”, añadimos las líneas de código necesarias a nuestra app para comunicarnos con estos servicios y nos sentamos a esperar a que amablemente nos envíen la información del usuario que hemos requerido.

En cuanto a la información que pedimos del usuario, ¿qué necesitamos y qué no? Permisos excesivos son sospechosos. Seamos sinceros, esa aplicación de Twitter no debería poder postear mensajes en tu nombre. Esa otra aplicación de Facebook no debería invitar a todos mis amigos a los eventos más pingües jamás creados. Sin embargo, permisos demasiado escuetos pueden no ajustarse a la previsión de futuro que tenemos para nuestra app o servicio. “En esta release no, pero en el futuro quiero que el usuario pueda publicar/compartir/seguir/darle al like en…”

Y sabes que, pongas los permisos que pongas, vas a tener problemas con tus usuarios. Porque seamos sinceros, hay dos tipos de personas, y el punto medio entre las dos suele ser muy escaso. El usuario o acepta alegremente la conexión de cualquier app con su perfil en la red social, pues para él no es más que un paso molesto para conseguir lo que quiere (y realmente no sabe lo que es un permiso), o se mirará concienzudamente todo lo que la app pide y le pesará en la conciencia hasta dar el nombre (¿¿para qué quieren saber los cotillas estos mi nombre??).

Facebook (ya alcanzando el meollo del post) encontró una solución a esto a través de su nuevo sistema de permisos en las últimas versiones del SDK. Tú como desarrollador pides amablemente lo que necesites (acceder a nombre, email, fecha de nacimiento, permiso para publicar etc). Entonces el usuario podrá rechazar cada uno de estos permisos de manera individual (manos a la cabeza, esto es un sinsentido), y cuando Facebook te conteste con los permisos que tu usuario (pues al fin y al cabo, además de ser usuario de Facebook, va a ser  usuario) ha aceptado/denegado, ya decides qué hacer.

FB te permite rechazar permisos tan alegremente

FB te permite rechazar permisos tan alegremente

Por supuesto, si te niegas a aceptar en tu servicio a alguien que haya denegado algún permiso, tienes que empezar a gestionar el logout ¡incluso aunque no se haya hecho login exitoso, pues el usuario ya ha conectado con tu app! Ni que decir tiene que este sistema me parece completamente ridículo, que es una forma que Facebook tiene de limpiarse las manos y que complica la vida al desarrollador más de lo que se la soluciona.

Así que opté por pasar del SDK oficial de Facebook y usé un wrapper para el mismo que se ajustaba más al esquema mental que tengo sobre los permisos de aplicaciones. android-simple-facebook te permite declarar de una manera sencilla los permisos que tu app requiere (mucho más sencilla que en el SDK oficial) y establecer un método dentro del correspondiente Listener que se ejecutará en el caso de que el usuario rechace un permiso o más de los que has pedido. Sin embargo, venía sin documentación integrada. Y cometí el error de no mirarme a fondo absolutamente toda la página correspondiente de StackOverflow (ya que el fallo que nos ocupa no aparece en la documentación oficial). Pues todo este sistema tiene una manzana envenenada, oculta en un caso límite muy límite, preparado para fastidiarte la existencia cuando menos te lo esperes.

Para tener una cuenta en Facebook necesitas un correo. Esto es evidente. Cuando te registras, Facebook te envía a tu dirección de correo un mensaje con un enlace de confirmación. Esto es bien sabido. De manera que así Facebook puede confirmar que la dirección de email que has reclamado como tuya lo es realmente. Esto es necesario, evidente y bien sabido. Sin embargo, si no confirmas tu dirección de correo pulsando ese enlace de confirmación, no pasa absolutamente nada. Puedes conectar aplicaciones a tu perfil que requieran tu email sin ningún tipo de problemas si eres el usuario. Alguien en Facebook se ha preocupado por ti, para que seas feliz en tu mundo de Candy Crush Saga y aplicaciones de horóscopo con colores fluorescentes. Pero Sergio, ¿cómo es posible que Facebook dé a terceros su dirección de email si no ha sido confirmada? Ahí está la trampa. El SDK (y el wrapper que he usado) no dirán ni mú, pues todos los permisos han sido completados. Sin embargo, en el campo email del objeto usuario se devolverá un brillante null, que, si no has sido precavido (como no lo fui yo), se colará en la tabla de usuarios de tu base de datos sin que nada en el sistema se queje.

Eso sí, si preguntas en Facebook, no es un bug, es una featureDe hecho, en el SDK oficial no hay una manera directa de obtener el email de usuario, al menos en su versión para Android. Tienes un objeto GraphUser sobre el que tienes que ejecutar .asMap() y sobre el Map<String, String> obtenido, hacer un get buscando por clave “email”. Todo eso, usando android-simple-facebook, queda tan sencillo como en el siguiente Gist (poniendo cada trozo de código en su correspondiente parte de una Actividad o Fragment, claro está).

Y me cabrea de sobremanera, pues alguien en Facebook ha pensado que era buena idea:

  • Primero, dejar que un usuario pueda conectar aplicaciones (requieran el permiso que requieran) sin haber confirmado su dirección de email.
  • Segundo, dejar que un usuario pueda conectar aplicaciones que pidan una dirección de email sin que esta esté confirmada.
  • Tercero, devolver un maldito null como email al desarrollador, sin otro indicador de que algo va mal y con esa posibilidad realmente escondida en la documentación de su SDK.

Así pues, recordad y repetid conmigo: a Facebook solo le importa Facebook. Algo muy legítimo, desde luego, cuando eres la red social más grande y activa del planeta.

Deja un comentario