I am implementing Google sign in on my app and I need to access the User ID and first/last name. The variables storing that data are in the App Delegate. I have searched the internet inside and out looking for how to do this in Swift 3, and there is absolutely nothing.
Here's the App Delegate (at least the part that matters):
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
var window: UIWindow?
var databaseRef: FIRDatabaseReference!
var userID = String()
var givenName = String()
var familyName = String()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    // Use Firebase library to configure APIs
    FIRApp.configure()
    GIDSignIn.sharedInstance().clientID = FIRApp.defaultApp()?.options.clientID
    GIDSignIn.sharedInstance().delegate = self
    return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    return GIDSignIn.sharedInstance().handle(url,
                                             sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
                                             annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
    if let error = error {
        print(error.localizedDescription)
        return
    }
    print("User signed into Google")
    let authentication = user.authentication
    let credential = FIRGoogleAuthProvider.credential(withIDToken: (authentication?.idToken)!,
                                                      accessToken: (authentication?.accessToken)!)
    FIRAuth.auth()?.signIn(with: credential) { (user, error) in
        print("User Signed Into Firebase")
        self.databaseRef = FIRDatabase.database().reference()
        self.databaseRef.child("user_profiles").child(user!.uid).observeSingleEvent(of: .value, with: { (snapshot) in
            let snapshot = snapshot.value as? NSDictionary
            if(snapshot == nil)
            {
                self.databaseRef.child("user_profiles").child(user!.uid).child("name").setValue(user?.displayName)
                self.databaseRef.child("user_profiles").child(user!.uid).child("email").setValue(user?.email)
            }
        })
    }
    userID = user.userID
    givenName = user.profile.givenName
    familyName = user.profile.familyName
    continueToWallet()
}
In the View Controller, I am calling the App delegate and trying to receive the data, but it gives me an error saying, "Instance member 'User ID' cannot be used on type 'AppDelegate'"
class addToWalletController: UIViewController {
var ID = String()
let delegate = UIApplication.shared.delegate as! AppDelegate
let user = AppDelegate.userID
let firstName = AppDelegate.givenName
let lastName = AppDelegate.familyName
override func viewDidLoad() {
    super.viewDidLoad()
}
}
I have also tried switching AppDelegate with delegate in the =AppDelegate.userID but it gives me the same error. What's going on?
Start a segue from any object that implements an action method, such as a control or gesture recognizer. You may also start segues from table rows and collection view cells. Right-click the control or object in your current view controller. Drag the cursor to the view controller you want to present.
AppDelegate is the class. What you want is the instance of AppDelegate that is your application's delegate. In addition, you can't use the delegate constant you've declared to set the values of other instance members because it is also an instance member itself. 
I like to implement a function in AppDelegate like this:
static func shared() -> AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate
}
And then I can just call it from elsewhere like so:
let firstName = AppDelegate.shared().givenName
Another option would be to set the values of these properties using the delegate property you have defined, but do it later such as in viewDidLoad, such as Alvin's answer suggests.
You can also made something similar to UIApplication.shared.... Than you have to add this to AppDelegates:
open class var shared: AppDelegate {
    get {
        return UIApplication.shared.delegate as! AppDelegate
    }
}
or something like this:
public class var shared: AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate
}
Than you have Swift 3.x syntax :)
Cheers!
The error message have told you property initializers run before 'self' is available.
Maybe you should initialize it in viewDidLoad
let delegate = UIApplication.shared.delegate as! AppDelegate
var user: String?
var firstName: String?
var lastName: String?
override func viewDidLoad() {
    super.viewDidLoad()
    user = delegate.userID
    firstName = delegate.givenName
    lastName = delegate.familyName
}
                        Update: You don't need to access Appdelegate for GoogleSignIn. Use following code in your button action
 @IBAction func loginWithGoogle(_ sender: Any) {
    GIDSignIn.sharedInstance().uiDelegate = self
    GIDSignIn.sharedInstance().signIn()
    //Be sure that you are signed-in
    if(GIDSignIn.sharedInstance().hasAuthInKeychain()){
        print("Signed-in")
        //Use currentUser attribute.
        print(GIDSignIn.sharedInstance().currentUser.profile.email)
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With