How can an extension add a custom attribute to the customers?

<?php
namespace Dfe\Facebook\Setup;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
class InstallSchema implements InstallSchemaInterface {
	/**
	 * 2015-10-06
	 * @override
	 * @see InstallSchemaInterface::install()
	 * @param SchemaSetupInterface $setup
	 * @param ModuleContextInterface $context
	 * @return void
	 */
	public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) {
		$setup->startSetup();
		$setup->getConnection()->addColumn(rm_table('customer_entity'),
			self::F__FACEBOOK_ID, 'varchar(25) DEFAULT NULL'
		);
		$setup->endSetup();
	}

	/**
	 * @used-by \Dfe\Facebook\Setup\InstallSchema::install()
	 * @used-by \Dfe\Facebook\Setup\InstallData::install()
	 */
	const F__FACEBOOK_ID = 'dfe_facebook_id';
}
<?php
namespace Dfe\Facebook\Setup;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
class InstallData implements InstallDataInterface {
	/**
	 * 2015-10-06
	 * @override
	 * @see InstallDataInterface::install()
	 * @param ModuleDataSetupInterface $setup
	 * @param ModuleContextInterface $context
	 * @return void
	 */
	public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context) {
		df_eav()->addAttribute('customer', InstallSchema::F__FACEBOOK_ID, array(
			'type' => 'static',
			'label' => 'Facebook ID',
			'input' => 'text',
			'sort_order' => 1000,
			'position' => 1000,
			'visible' => false,
			'system' => false,
			'required' => false
		));
		/** @var int $attributeId */
		$attributeId = rm_first(rm_fetch_col(
			'eav_attribute', 'attribute_id', 'attribute_code', InstallSchema::F__FACEBOOK_ID
		));
		rm_conn()->insert(rm_table('customer_form_attribute'), array(
			'form_code' => 'adminhtml_customer', 'attribute_id' => $attributeId
		));
	}
}
/**
 * @return \Magento\Eav\Setup\EavSetup'
 */
function df_eav() {return df_o('Magento\Eav\Setup\EavSetup');}

Some more words about the visible parameter.
In becomes the value of is_visible column of customer_eav_attribute table.
If set it to true then the attribute will be shown in the admin customer form:

A similar code is used in my «Facebook Login» Magento 2 extension.

See also:

Thanks for the useful article! I’m able to save the value of custom attribute from backend but not from frontend, can you please help me to save the custom attribute’s value from frontend?

Thanks in advance!

In Magento 1.x many model types are not allowed to be saved from the frontend for security reasons: http://magento.stackexchange.com/a/16649
I think Magento 2 inherits such bevaviour.