I am using the FB Registration plugin with the following code:
<html xmlns:fb="http://ogp.me/ns/fb#">
<script type="text/javascript">
window.fbAsyncInit = function() { FB.init({appId: 'xxx', status: true, cookie: true, xfbml: true}); };
(function() {
var e = document.createElement('script');
e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
})();
</script>
and here is my desired list of fields:
<?php /* There seems to be a character limit for fields causing "invalid client_id" on log in/out */?>
<fb:registration redirect-uri="https://xxx.secure.xxx.com/register/fb_submit.php"
fields='[
{"name":"name","view":"prefilled"},
{"name":"email"},
{"name":"password"},
{"name":"s_question","description":"Secret Question","type":"select","options":{"2":"In which city were you born?","4":"What is your favorite book?","3":"What is your favorite pets name?","6":"What is your favorite vacation spot?","1":"What is your mothers maiden name?"}},
{"name":"s_answer","type":"text","description":"Secret Answer"},
{"name":"first_name"},
{"name":"last_name"},
{"name":"address_co","description":"Care of (Optional)","type":"text","no_submit":true},
{"name":"address","description":"Mailing Address","type":"text"},
{"name":"address2","description":"Apartment/Unit","type":"text","no_submit":true},
{"name":"street_address","description":"Street Address (if using a P.O. box above)","type":"text","no_submit":true},
{"name":"location","view":"prefilled"},
{"name":"city","view":"not_prefilled","description":"City","type":"text"},
{"name":"state","view":"not_prefilled", "description":"State","type":"select","options":{"AA":"AA - Armed Forces Americas","AE":"AE - Armed Forces","AK":"AK - Alaska","AL":"AL - Alabama","AP":"AP - Armed Forces Pacific","AR":"AR - Arkansas","AS":"AS - American Samoa","AZ":"AZ - Arizona","CA":"CA - California","CO":"CO - Colorado","CT":"CT - Connecticut","DC":"DC - District of Columbia","DE":"DE - Delaware","FL":"FL - Florida","FM":"FM - Federated States of Micronesia","GA":"GA - Georgia","GU":"GU - Guam","HI":"HI - Hawaii","IA":"IA - Iowa","ID":"ID - Idaho","IL":"IL - Illinois","IN":"IN - Indiana","KS":"KS - Kansas","KY":"KY - Kentucky","LA":"LA - Louisiana","MA":"MA - Massachusetts","MD":"MD - Maryland","ME":"ME - Maine","MH":"MH - Marshall Islands","MI":"MI - Michigan","MN":"MN - Minnesota","MO":"MO - Missouri","MP":"MP - Northern Mariana Islands","MS":"MS - Mississippi","MT":"MT - Montana","NC":"NC - North Carolina","ND":"ND - North Dakota","NE":"NE - Nebraska","NH":"NH - New Hampshire","NJ":"NJ - New Jersey","NM":"NM - New Mexico","NV":"NV - Nevada","NY":"NY - New York","OH":"OH - Ohio","OK":"OK - Oklahoma","OR":"OR - Oregon","PA":"PA - Pennsylvania","PR":"PR - Puerto Rico","PW":"PW - Palau","RI":"RI - Rhode Island","SC":"SC - South Carolina","SD":"SD - South Dakota","TN":"TN - Tennessee","TX":"TX - Texas","UT":"UT - Utah","VA":"VA - Virginia","VI":"VI - Virgin Islands","VT":"VT - Vermont","WA":"WA - Washington","WI":"WI - Wisconsin","WV":"WV - West Virginia","WY":"WY - Wyoming"}},
{"name":"zip","description":"5-digit Zip Code","type":"text"},
{"name":"phone","description":"Phone (800-555-1212)","type":"text"},
{"name":"referred_by","description":"Referred by-Email or site nickname (Optional)","type":"text","no_submit":true},
{"name":"cert_code","description":"Gift Certificate Code (Optional)","type":"text","no_submit":true},
{"name":"sel_hear_about","description":"How Did You Hear About Us?","type":"select","options":{"1":"Friend","2":"Newspaper","3":"Magazine","4":"Internet Search","5":"Internet Ad","6":"Website","8":"site2","9":"site3","10":"Other","11":"TV","12":"Radio"}},
{"name":"hear_about","description":"newspaper/blog/website/friend name? (Optional) ","type":"text","no_submit":true},
{"name":"birthday"},
{"name":"hours","description":"Hours Spent Reading per Week (Optional)","type":"select","options":{"0":"0","1-5":"1-5","6-10":"6-10","11-20":"11-20","21-30":"21-30","31-40":"31-40","41+":"41+"},"no_submit":true}
]' onvalidate="validate">
</fb:registration>
and here is my validate() function:
function validate(form)
{
errors = {};
var dt = new Date(), expiryTime = dt.setTime( dt.getTime() + 1000*5 );
var expires = dt.toGMTString();
if (form.first_name == "")
{
errors.first_name = "Please choose a First Name";
}
if (form.s_question == "-1")
{
errors.s_question = "Please choose a Secret Question";
}
if (form.s_answer == "")
{
errors.s_answer = "Please type an answer to your Secret Question";
}
if (form.address_co !== "")
{
set_cookie( 'address_co', form.address_co, expires, '/register', 'secure.xxx.com', true );
}
if (form.address == "")
{
errors.address = "Please type your mailing address";
}
if (form.address2 !== "")
{
set_cookie( 'address2', form.address2, expires, '/register', 'secure.xxx.com', true );
}
if (form.street_address !== "")
{
set_cookie( 'street_address', form.street_address, expires, '/register', 'secure.xxx.com', true );
}
if (form.zip == "")
{
errors.zip = "Please type a 5-digit Zip Code"
}
else if (form.zip.length != 5)
{
errors.zip = "Zip Code must be 5 digits";
}
else if (isNaN(form.zip))
{
errors.zip = "Zip Code must be a number";
}
if (form.phone == "")
{
errors.phone = "Please type your phone number";
}
if (form.referred_by !== "")
{
set_cookie( 'referred_by', form.referred_by, expires, '/register', 'secure.xxx.com', true );
}
if (form.cert_code !== "")
{
set_cookie( 'cert_code', form.cert_code, expires, '/register', 'secure.xxx.com', true );
}
if (!form.sel_hear_about)
{
errors.sel_hear_about = "Please choose how you heard about us";
}
if (form.hear_about !== "")
{
set_cookie( 'hear_about', form.hear_about, expires, '/register', 'secure.xxx.com', true );
}
if (form.hours !== "-1")
{
set_cookie( 'hours', form.hours, expires, '/register', 'secure.xxx.com', true );
}
return errors;
}
If the user is already logged into FB when visiting this reg form, the FB fields are populated and the form works. However, if the user is not logged into FB and chooses the FB prompt on the form “Log in to prefill the form below with your profile information.”, then provides login credentials to FB, the form disappears and is replaced by the rather generic ‘client_id’ error from FB.
If the user then refreshes the page, s/he has been logged into FB and the proper FB fields are populated.
I have validated the JSON field list. During testing, I found that if I reduced the field list to:
fields='[
{"name":"name","view":"prefilled"},
{"name":"email"},
{"name":"password"},
{"name":"s_question","description":"Secret Question","type":"select","options":{"2":"In which city were you born?","4":"What is your favorite book?","3":"What is your favorite pets name?","6":"What is your favorite vacation spot?","1":"What is your mothers maiden name?"}},
{"name":"s_answer","type":"text","description":"Secret Answer"},
{"name":"first_name"},
{"name":"last_name"}, ]' onvalidate="validate">
then I did not get the error. If I add the longest field (state field from above) back in, the client_id error returns. Instead of adding state, I can add a combination of other shorter fields and get the same error. This makes me think that I’m hitting some kind of max size limit for the JSON field list. Probably not for the actual JSON that’s sent to FB, but in the corresponding hidden fields that FB sends back after logging in.
If I am unable to fix this, I plan to get only the basic FB fields and move the rest to another page. Of course I prefer to leave it in one piece since the form and my supporting reg. code all work after the FB data is loaded into the form (on refresh).
Thank you for your patience with this lengthy description.
I don’t have any fix for this, I can only offer a possible (no, I actually think the most likely) explanation:
What the
<fb:registration>tag does, like all the other plugins, is basically creating an iframe in your page, that gets all it’s necessary parameters passed in the query string as GET parameters.So, a lot of fields defined by you for the registration form means a long query string in the iframe’s URL.
The problem is, browsers limit the possible length of an URL – see https://stackoverflow.com/a/417184/1427878, http://www.boutell.com/newfaq/misc/urllength.html
And web servers do it as well, before they say, “uh, that’s a little much for me to process via GET, so sorry, but no sorry …”
So while your registration form might work with lots of fields defined when the user is already logged in, because the length of the iframe URL stays under the limits enforced by your browser or Facebook’s servers – if the user is not logged in and clicks on the login button, they are redirected through the Facebook Auth flow, and the URL that they should be “send back to” after successful login (the address of the registration form with all its GET parameters in this case) is transfered as a GET parameter in the Auth dialog URL, amongst other parameters. (And the necessary URL encoding to be applied when transmitting an URL as a GET parameter within another URL blows it up even more …)
And that results in a really long URL, that can not be transmitted/processed any more with the limits enforced by either browsers or Facebook’s servers. (Since you are getting an error message by Facebook, it’s most likely Facebook’s servers are refusing to process it in this scenario.)
So, you could go try and open a bug report with Facebook – them setting the limits for maximal GET URL length could fix this problem; but if they’ll be willing to do this, might be another question. (Because allowing longer request URLs might have other implications as well.)
And even if they did, you might still hit road blocks with the browsers your users are using – if the current limit in Internet Explorer is still 2,048 characters for the path part of an URL, that might be the next part where the registration form with to many fields will break on the frontend …