Some of the things you are reading are old information. @synthesize used to be required (and still can be used), but it is automatically added for you now during compilation (and you should generally use that option).
You don't need -(NSString *) firstName;
in the @interface, because the @property definition is already defining that.
// DO I NEED THE CODE BELOW OR ARE THESE AUTO-CREATED?
No, you don't need it, it is auto-generated for you. You would only implement the methods yourself if you wanted to do something special. Usually the auto-generated versions are great because you specify how the methods should be implemented in the @property definition (nonatomic, strong)
and that it taken care of for you. If you implement the methods yourself then you are subverting that (so the @property definition could become a lie...).
aClass.firstName = @"Richard"; //Does this call setFirstName?
Yes it does. The compiler actually converts it into:
[aClass setFirstName:@"Richard"];
for you.