I've been struggling to make the facebook login button work for awhile. I tried to search around and tried several solutions from others but still couldn't get it sorted out.
The problem is Facebook Login Button show as empty red borders box.
I followed all the instructions on facebook site as well as react-native-fbsdk github documentation but still no luck.
Output from rnpm link below
rnpm-link info iOS module apphub is already linked
rnpm-link info Android module react-native-facebook-login is already linked
rnpm-link info iOS module react-native-facebook-login is already linked
rnpm-link info Android module react-native-fbsdk is already linked
rnpm-link info iOS module react-native-fbsdk is already linked
react-native-fbsdk is already linked
Output from react-native log-ios
Apr 15 21:27:16 MacBook-Pro-3 App[28314] <Warning>: Warning: Native component for "RCTFBLikeView" does not exist
Apr 15 21:27:16 MacBook-Pro-3 App[28314] <Warning>: Warning: Native component for "RCTFBLoginButton" does not exist
Apr 15 21:27:16 MacBook-Pro-3 App[28314] <Warning>: Warning: Native component for "RCTFBSendButton" does not exist
Apr 15 21:27:16 MacBook-Pro-3 App[28314] <Warning>: Warning: Native component for "RCTFBShareButton" does not exist
XCode Libraries
AppDelegate.m
FacebookLoginButton Component
import React, { PropsType, Component } from 'react';
import {
View
} from 'react-native';
const FBSDK = require('react-native-fbsdk');
const {
LoginButton,
AccessToken
} = FBSDK;
class FacebookLoginButton extends Component {
render() {
return (
<View>
<LoginButton
publishPermissions={["publish_actions"]}
onLoginFinished={
(error, result) => {
if (error) {
alert("login has error: " + result.error);
} else if (result.isCancelled) {
alert("login is cancelled.");
} else {
AccessToken.getCurrentAccessToken().then(
(data) => {
alert(data.accessToken.toString())
}
)
}
}
}
onLogoutFinished={() => alert("logout.")}/>
</View>
);
}
};
export { FacebookLoginButton };
Login Component
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { View, TextInput, KeyboardAvoidingView } from 'react-native';
import firebase from 'firebase';
import { emailChanged, passwordChanged, loginUser } from '../../actions';
import { Button, CardSection, Input, Spinner, FacebookLoginButton } from '../common';
class Login extends Component {
onEmailChange(text) {
this.props.emailChanged(text);
}
onPasswordChange(text) {
this.props.passwordChanged(text);
}
onLoginButtonPress() {
const { email, password } = this.props;
console.log('logging in');
this.props.loginUser({ email, password });
}
onFacebookLoginButtonPress() {
console.log('logging in with facebook');
var provider = new firebase.auth.FacebookAuthProvider();
provider.addScope('user_birthday');
firebase.auth().signInWithPopup(provider).then(function(result) {
// This gives you a Facebook Access Token.
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
});
}
renderButton() {
console.log(this.props);
switch (this.props.loading) {
case true:
return (<Spinner size="large" />)
break;
default:
return (
<View>
<Button
onPress={this.onLoginButtonPress.bind(this)}
buttonStyleOverride={[styles.buttonStyle]}
textStyleOverride={[styles.loginButtonText]}
>เข้าสู่ระบบ</Button>
<Button
onPress={this.onFacebookLoginButtonPress.bind(this)}
buttonStyleOverride={[styles.buttonStyle, styles.facebookButton]}
textStyleOverride={[styles.facebookButtonText]}
>Login with Facebook</Button>
<FacebookLoginButton />
</View>
);
}
}
render() {
return (
<KeyboardAvoidingView behavior="padding" style={styles.container}>
<View style={styles.formContainer}>
<TextInput
placeholder="Email Address"
autoCorrect={false}
style={styles.inputStyle}
onChangeText={this.onEmailChange.bind(this)}
value={this.props.email}
/>
<TextInput
placeholder="Password"
autoCorrect={false}
style={styles.inputStyle}
onChangeText={this.onPasswordChange.bind(this)}
value={this.props.password}
/>
</View>
<View style={styles.buttonContainer}>
{this.renderButton()}
</View>
</KeyboardAvoidingView>
);
}
}
const mapStateToProps = ({ auth }) => {
const { email, password, error, loading } = auth;
return { email, password, error, loading };
};
const styles = {
container: {
marginTop: -65,
flexDirection: 'column',
flex: 1,
backgroundColor: '#f8f8f8'
},
formContainer: {
flexDirection: 'column',
justifyContent: 'flex-end',
alignItems: 'center',
flex: 2,
paddingLeft: 60,
paddingRight: 60,
paddingBottom: 60,
},
inputStyle: {
color: '#646464',
paddingRight: 15,
paddingLeft: 15,
fontSize: 16,
lineHeight: 23,
backgroundColor: '#fff',
height: 50,
borderBottomWidth: 1,
borderBottomColor: '#eee',
marginBottom: 15,
},
buttonContainer: {
justifyContent: 'flex-start',
flexDirection: 'column',
borderColor: '#ddd',
position: 'relative',
marginBottom: 10,
paddingLeft: 60,
paddingRight: 60,
flex: 1,
},
buttonStyle: {
position: 'relative',
borderRadius: 999,
marginBottom: 15,
borderColor: '#F4B9BF',
backgroundColor: '#F4B9BF',
flex: 0,
},
loginButtonText: {
fontFamily: 'Prompt',
fontWeight: '400',
color: '#FFF',
lineHeight: 24,
},
facebookButton: {
backgroundColor: '#007aff'
},
facebookButtonText: {
color: '#fff',
lineHeight: 24,
}
};
export default connect(mapStateToProps, {
emailChanged,
passwordChanged,
loginUser
})(Login);
I figured out the problem, what went wrong was how I implement the code in AppDelegate.m
It should be looking like this
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
// Facebook SDK Installation
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index.ios" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:#"fongdue"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
];
// Add any custom logic here.
return handled;
}
#end
Now the button is showing and working as expected
Related
I introduced SideMenu in CocoaPods, but an error occurs in the ios13 part of the status bar.But I don't know the correct code.
Would you please teach me?
var statusBarFrame: CGRect {
if #available(iOS 13.0, *) {
// How to do for iOS 13??
} else {
return UIApplication.shared.statusBarFrame
}
}
statusBarFrame has been deprecated in iOS 13,
for iOS 13 you can use this
var statusBarFrame: CGRect {
if #available(iOS 13.0, *) {
return UIApplication.shared.keyWindow!.windowScene!.statusBarManager!.statusBarFrame
} else {
return UIApplication.shared.statusBarFrame
}
}
I have a page on my application that has a Modal Page and I want to change the size of that page, I try to use the model property to change it but it will change the size of all the other ones and I want to have different models with different sizes
$modal-inset-min-width
Add this into your app.scss:
.my-modal {
height: 50%!important;
width: 50%!important;
}
I used the suggested approach to launch a modal with 50% height, but I found the problem of not having enabled the backdrop.
//app.scss
.my-modal {
height: 50%!important;
transform: translateY(100%);
}
outputs:
so I ended up with:
//app.scss
#include media-breakpoint-down(sm) {
.my-modal {
ion-backdrop {
visibility: visible !important;
}
.modal-wrapper {
border-radius: 10px 10px 0px 0px;
overflow: hidden;
top: 50%;
left: 0;
position: absolute;
width: 100%;
height: 50%;
}
}
}
that output these views:
I used the breakpoint mixin to keep the modal behavior in 768+ px (tablets, etc).
Hope helps somebody.
If you see inside create method of ModalController, it is:
create(component: any, data?: any, opts?: ModalOptions): Modal;
And here is ModalOptions:
export interface ModalOptions {
showBackdrop?: boolean;
enableBackdropDismiss?: boolean;
enterAnimation?: string;
leaveAnimation?: string;
cssClass?: string;
}
So, just add a class to your modal like that:
let modal = this.mModalController.create("YourModalPage","Your data",{
cssClass: "my-modal"
})
And now you can style for your modal by .my-modal class
Put his Code into your app.scss file
modal-wrapper {
position: absolute;
width: 100%;
height: 100%;
}
#media not all and (min-height: 600px) and (min-width: 768px) {
ion-modal ion-backdrop {
visibility: hidden;
}
}
#media only screen and (min-height: 0px) and (min-width: 0px) {
.modal-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
Modal Controller takes a custom css
let moreInfoModal = this.modalCtrl.create(DesktopMoreInfoPage, {
titles: title,
images: image,
description: description
}, {cssClass: 'custom-class'});
moreInfoModal.present();
Then in your app.scss file
.custom-class {
//your styling goes here
}
Custom css
ion-modal.my-modal {
padding: 10vh 10vw;
}
Custom ts
this.modalCtrl.create(pageName, {myParam:item}, { cssClass: 'my-modal' });
I want to create custom dialog box in ionic2. I have tried lot's of reference ionic docs tutorial but I am not getting what I want.
I want to show this when user click on icon.
Please give me some idea to achieve the same.
You can use an ionic modal with a custom class name,so you override the css only for this popup
to open the popup:
openModal() {
let modal = this.modalCtrl.create(CustomPopup,{},{showBackdrop:true, enableBackdropDismiss:true});
modal.present();
}
component used in modal:
import { Component, Renderer } from '#angular/core';
import { ViewController } from 'ionic-angular';
#Component({
selector: 'custom-popup',
templateUrl: 'custom-popup.html'
})
export class CustomPopup {
text: string;
constructor(public renderer: Renderer, public viewCtrl: ViewController) {
this.renderer.setElementClass(viewCtrl.pageRef().nativeElement, 'custom-popup', true);
}
}
and finaly the SCSS:
ion-modal.custom-popup ion-backdrop {
visibility: visible !important;
z-index:0;
}
ion-modal.custom-popup .modal-wrapper{
top: 20%;
width:60%;
height:300px;
position:absolute;
}
You can add create custom controller as below -
import { AlertController } from 'ionic-angular';
constructor(private alertCtrl: AlertController) {
}
presentAlert() {
let alert = this.alertCtrl.create({
title: 'Low battery',
subTitle: '10% of battery remaining',
cssClass: 'my-class',
buttons: ['Dismiss']
});
alert.present();
}
<style>
.my-class{
background: gray;
color:#333;
}
</style>
On the same way you can add your custom style. You can get complete example on - https://www.tutorialsplane.com/ionic-popup
If it's possible, is it an easy implementation or a tough one?
I had difficulty getting a clear idea in Flutter.io's documentation.
You can use platform channel for this. It shouldn't be tough. You need to add handlers in native code and redirect urls via channels to flutter code.
Example for iOS:
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
FlutterViewController *controller = (FlutterViewController*)self.window.rootViewController;
self.urlChannel = [FlutterMethodChannel methodChannelWithName:#"com.myproject/url" binaryMessenger:controller];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
[self.urlChannel invokeMethod:#"openURL"
arguments:#{#"url" : url.absoluteString}];
return true;
}
#end
And basic flutter code:
class _MyHomePageState extends State<MyHomePage> {
final MethodChannel channel = const MethodChannel("com.myproject/url");
String _url;
#override
initState() {
super.initState();
channel.setMethodCallHandler((MethodCall call) async {
debugPrint("setMethodCallHandler call = $call");
if (call.method == "openURL") {
setState(() => _url = call.arguments["url"]);
}
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(_url ?? "No URL"),
),
);
}
}
For anyone need updated solution:
you can use Google Dynamic Links for Firebase and another guideline on Medium
How Do I draw a line in Titanium that works in both Android and iPhone?
To create a line, I use;
var view = Ti.UI.createView({
height:180,
width:300
});
var line = Ti.UI.createView({
height:2,
bottom:0,
left:0,
right:0,
borderWidth:1,
borderColor:'#aaa'
});
view.add(line);
Add this to your view.xml
<View class="line"></View>
Add this to your style.tss
".line": {
height: '2dp',
bottom: '2dp',
left: '0dp',
right: '0dp',
borderWidth: '1',
borderColor:'#aaa',
}
you could create webview and use the <canvas> tag to draw in the web view