├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github └── workflows │ └── integrate.yml ├── .gitignore ├── .npmignore ├── .prettierrc ├── .watchmanconfig ├── Example ├── .eslintrc.js ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .prettierrc.js ├── .watchmanconfig ├── App.js ├── README.md ├── android │ ├── app │ │ ├── build.gradle │ │ ├── build_defs.bzl │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios │ ├── Example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── Example-tvOS.xcscheme │ │ │ └── Example.xcscheme │ ├── Example.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Example │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── main.m │ ├── ExampleTests │ │ ├── ExampleTests.m │ │ └── Info.plist │ ├── Podfile │ └── Podfile.lock ├── metro.config.js ├── package.json └── yarn.lock ├── LICENSE ├── README.md ├── RNAdMobBanner.js ├── RNAdMobInterstitial.js ├── RNAdMobRewarded.js ├── RNPublisherBanner.js ├── android ├── RNAdMob.iml ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── sbugert │ │ └── rnadmob │ │ ├── RNAdMobBannerViewManager.java │ │ ├── RNAdMobInterstitialAdModule.java │ │ ├── RNAdMobPackage.java │ │ ├── RNAdMobRewardedVideoAdModule.java │ │ └── RNPublisherBannerViewManager.java │ └── res │ └── values │ └── strings.xml ├── index.js ├── ios ├── RCTConvert+GADAdSize.h ├── RCTConvert+GADAdSize.m ├── RNAdMobInterstitial.h ├── RNAdMobInterstitial.m ├── RNAdMobManager.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── RNAdMobRewarded.h ├── RNAdMobRewarded.m ├── RNAdMobUtils.h ├── RNAdMobUtils.m ├── RNDFPBannerView.h ├── RNDFPBannerView.m ├── RNDFPBannerViewManager.h ├── RNDFPBannerViewManager.m ├── RNGADBannerView.h ├── RNGADBannerView.m ├── RNGADBannerViewManager.h └── RNGADBannerViewManager.m ├── package.json ├── react-native-admob.podspec └── utils.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [*.{js,json}] 16 | indent_size = 2 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.js 2 | !/*.js 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es6": true, 4 | "node": true 5 | }, 6 | "extends": ["plugin:prettier/recommended", "plugin:react/recommended"], 7 | "parser": "babel-eslint", 8 | "parserOptions": { 9 | "ecmaVersion": 6 10 | }, 11 | "plugins": [ 12 | "react", 13 | "react-native" 14 | ], 15 | "rules": { 16 | "comma-dangle": ["error", "always-multiline"], 17 | "react/jsx-handler-names": "error" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/integrate.yml: -------------------------------------------------------------------------------- 1 | name: Integrate React Native AdMob 2 | on: 3 | schedule: 4 | - cron: 0 12 * * 1 5 | pull_request: 6 | branches: 7 | - master 8 | jobs: 9 | integrate: 10 | name: Create React Native App and integrate React Native Admob 11 | runs-on: macOS-latest 12 | steps: 13 | - uses: actions/checkout@v1 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: '10.x' 17 | - name: Install xmlstarlet 18 | run: brew install xmlstarlet 19 | - name: Install xcpretty 20 | run: gem install xcpretty 21 | - name: Configure Xcode 22 | run: sudo xcode-select --switch /Applications/Xcode_11.app 23 | - name: Install React Native CLI 24 | run: sudo npm install -g react-native-cli 25 | - name: Initialize React Native application 26 | run: react-native init ReactNativeAdMobExample 27 | - name: Add react-native-admob 28 | working-directory: ./ReactNativeAdMobExample 29 | run: yarn add react-native-admob@next 30 | - name: Configure Android Project 31 | working-directory: ./ReactNativeAdMobExample 32 | run: | 33 | xml ed -L \ 34 | -s /manifest/application -t elem -n meta-data \ 35 | -i /manifest/application/meta-data -t attr -n android:name -v "com.google.android.gms.ads.APPLICATION_ID" \ 36 | -i /manifest/application/meta-data -t attr -n android:value -v "ca-app-pub-3940256099942544~1458002511" \ 37 | ./android/app/src/main/AndroidManifest.xml 38 | - name: Configure iOS Project 39 | working-directory: ./ReactNativeAdMobExample/ios 40 | run: | 41 | cp ../../Example/ios/ExampleTests/ExampleTests.m ./ReactNativeAdMobExampleTests/ReactNativeAdMobExampleTests.m 42 | sed -i -e '/target '"'"'ReactNativeAdMobExample'"'"' do/a\ 43 | pod '"'"'Google-Mobile-Ads-SDK'"'"' 44 | ' Podfile 45 | /usr/libexec/PlistBuddy -c 'Add :GADApplicationIdentifier string ca-app-pub-3940256099942544~1458002511' \ 46 | ReactNativeAdMobExample/Info.plist 47 | pod install 48 | - name: Update App.js 49 | working-directory: ./ReactNativeAdMobExample 50 | run: cp ../Example/App.js ./App.js 51 | - name: Start packager 52 | working-directory: ./ReactNativeAdMobExample 53 | run: react-native start & 54 | - name: Run iOS 55 | working-directory: ./ReactNativeAdMobExample 56 | run: react-native run-ios --simulator "iPhone 11 Pro" 57 | - name: Take screenshot after delay 58 | run: sleep 30 && xcrun simctl io booted screenshot screenshot.png 59 | - uses: actions/upload-artifact@master 60 | with: 61 | name: screenshot 62 | path: ./screenshot.png 63 | - name: Run iOS tests 64 | working-directory: ./ReactNativeAdMobExample/ios 65 | run: | 66 | set -o pipefail && xcodebuild \ 67 | -workspace ReactNativeAdMobExample.xcworkspace \ 68 | -scheme ReactNativeAdMobExample \ 69 | -sdk iphonesimulator \ 70 | -destination 'platform=iOS Simulator,name=iPhone 11 Pro' \ 71 | test | xcpretty 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | .DS_Store 3 | 4 | # Xcode 5 | # 6 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 7 | 8 | ## Build generated 9 | build/ 10 | DerivedData 11 | 12 | ## Various settings 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata 22 | 23 | ## Other 24 | *.xccheckout 25 | *.moved-aside 26 | *.xcuserstate 27 | *.xcscmblueprint 28 | 29 | ## Obj-C/Swift specific 30 | *.hmap 31 | *.ipa 32 | 33 | # CocoaPods 34 | # 35 | # We recommend against adding the Pods directory to your .gitignore. However 36 | # you should judge for yourself, the pros and cons are mentioned at: 37 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 38 | # 39 | # Pods/ 40 | 41 | # Carthage 42 | # 43 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 44 | # Carthage/Checkouts 45 | 46 | Carthage/Build 47 | 48 | # fastlane 49 | # 50 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 51 | # screenshots whenever they are needed. 52 | # For more information about the recommended setup visit: 53 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 54 | 55 | fastlane/report.xml 56 | fastlane/screenshots 57 | 58 | node_modules/**/* 59 | 60 | # Android 61 | android/.idea/ 62 | android/android.iml 63 | android/RNAdMob.iml 64 | android/gradle/ 65 | android/gradlew 66 | android/gradlew.bat 67 | android/local.properties 68 | Example/android/Example.iml 69 | Example/android/app/app.iml 70 | Example/.buckconfig 71 | Example/.vscode/ 72 | Example/android/app/BUCK 73 | /yarn.lock 74 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | Example/ 2 | android/.idea/ 3 | android/android.iml 4 | android/RNAdMob.iml 5 | android/gradle/ 6 | android/gradlew 7 | android/gradlew.bat 8 | android/local.properties 9 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5", 4 | "proseWrap": "always", 5 | "arrowParens": "always" 6 | } 7 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["Example", "node_modules"] 3 | } 4 | -------------------------------------------------------------------------------- /Example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | }; 5 | -------------------------------------------------------------------------------- /Example/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | node_modules/react-native/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | node_modules/react-native/Libraries/polyfills/.* 18 | 19 | ; These should not be required directly 20 | ; require from fbjs/lib instead: require('fbjs/lib/warning') 21 | node_modules/warning/.* 22 | 23 | ; Flow doesn't support platforms 24 | .*/Libraries/Utilities/HMRLoadingView.js 25 | 26 | [untyped] 27 | .*/node_modules/@react-native-community/cli/.*/.* 28 | 29 | [include] 30 | 31 | [libs] 32 | node_modules/react-native/Libraries/react-native/react-native-interface.js 33 | node_modules/react-native/flow/ 34 | 35 | [options] 36 | emoji=true 37 | 38 | esproposal.optional_chaining=enable 39 | esproposal.nullish_coalescing=enable 40 | 41 | module.file_ext=.js 42 | module.file_ext=.json 43 | module.file_ext=.ios.js 44 | 45 | module.system=haste 46 | module.system.haste.use_name_reducers=true 47 | # get basename 48 | module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' 49 | # strip .js or .js.flow suffix 50 | module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' 51 | # strip .ios suffix 52 | module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' 53 | module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' 54 | module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' 55 | module.system.haste.paths.blacklist=.*/__tests__/.* 56 | module.system.haste.paths.blacklist=.*/__mocks__/.* 57 | module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* 58 | module.system.haste.paths.whitelist=/node_modules/react-native/RNTester/.* 59 | module.system.haste.paths.whitelist=/node_modules/react-native/IntegrationTests/.* 60 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/react-native/react-native-implementation.js 61 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* 62 | 63 | munge_underscores=true 64 | 65 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 66 | 67 | suppress_type=$FlowIssue 68 | suppress_type=$FlowFixMe 69 | suppress_type=$FlowFixMeProps 70 | suppress_type=$FlowFixMeState 71 | 72 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) 73 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ 74 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 75 | 76 | [lints] 77 | sketchy-null-number=warn 78 | sketchy-null-mixed=warn 79 | sketchy-number=warn 80 | untyped-type-import=warn 81 | nonstrict-import=warn 82 | deprecated-type=warn 83 | unsafe-getters-setters=warn 84 | inexact-spread=warn 85 | unnecessary-invariant=warn 86 | signature-verification-failure=warn 87 | deprecated-utility=error 88 | 89 | [strict] 90 | deprecated-type 91 | nonstrict-import 92 | sketchy-null 93 | unclear-type 94 | unsafe-getters-setters 95 | untyped-import 96 | untyped-type-import 97 | 98 | [version] 99 | ^0.98.0 100 | -------------------------------------------------------------------------------- /Example/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # CocoaPods 59 | /ios/Pods/ 60 | -------------------------------------------------------------------------------- /Example/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: true, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | }; 7 | -------------------------------------------------------------------------------- /Example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /Example/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | Button, 4 | Platform, 5 | ScrollView, 6 | StyleSheet, 7 | Text, 8 | View, 9 | } from 'react-native'; 10 | import { 11 | AdMobBanner, 12 | AdMobInterstitial, 13 | AdMobRewarded, 14 | PublisherBanner, 15 | } from 'react-native-admob'; 16 | 17 | const BannerExample = ({ style, title, children, ...props }) => ( 18 | 19 | {title} 20 | {children} 21 | 22 | ); 23 | 24 | const bannerWidths = [200, 250, 320]; 25 | 26 | export default class Example extends Component { 27 | constructor() { 28 | super(); 29 | this.state = { 30 | fluidSizeIndex: 0, 31 | }; 32 | } 33 | 34 | componentDidMount() { 35 | AdMobRewarded.setTestDevices([AdMobRewarded.simulatorId]); 36 | AdMobRewarded.setAdUnitID('ca-app-pub-3940256099942544/5224354917'); 37 | 38 | AdMobRewarded.addEventListener('rewarded', reward => 39 | console.log('AdMobRewarded => rewarded', reward), 40 | ); 41 | AdMobRewarded.addEventListener('adLoaded', () => 42 | console.log('AdMobRewarded => adLoaded'), 43 | ); 44 | AdMobRewarded.addEventListener('adFailedToLoad', error => 45 | console.warn(error), 46 | ); 47 | AdMobRewarded.addEventListener('adOpened', () => 48 | console.log('AdMobRewarded => adOpened'), 49 | ); 50 | AdMobRewarded.addEventListener('videoStarted', () => 51 | console.log('AdMobRewarded => videoStarted'), 52 | ); 53 | AdMobRewarded.addEventListener('adClosed', () => { 54 | console.log('AdMobRewarded => adClosed'); 55 | AdMobRewarded.requestAd().catch(error => console.warn(error)); 56 | }); 57 | AdMobRewarded.addEventListener('adLeftApplication', () => 58 | console.log('AdMobRewarded => adLeftApplication'), 59 | ); 60 | 61 | AdMobRewarded.requestAd().catch(error => console.warn(error)); 62 | 63 | AdMobInterstitial.setTestDevices([AdMobInterstitial.simulatorId]); 64 | AdMobInterstitial.setAdUnitID('ca-app-pub-3940256099942544/1033173712'); 65 | 66 | AdMobInterstitial.addEventListener('adLoaded', () => 67 | console.log('AdMobInterstitial adLoaded'), 68 | ); 69 | AdMobInterstitial.addEventListener('adFailedToLoad', error => 70 | console.warn(error), 71 | ); 72 | AdMobInterstitial.addEventListener('adOpened', () => 73 | console.log('AdMobInterstitial => adOpened'), 74 | ); 75 | AdMobInterstitial.addEventListener('adClosed', () => { 76 | console.log('AdMobInterstitial => adClosed'); 77 | AdMobInterstitial.requestAd().catch(error => console.warn(error)); 78 | }); 79 | AdMobInterstitial.addEventListener('adLeftApplication', () => 80 | console.log('AdMobInterstitial => adLeftApplication'), 81 | ); 82 | 83 | AdMobInterstitial.requestAd().catch(error => console.warn(error)); 84 | } 85 | 86 | componentWillUnmount() { 87 | AdMobRewarded.removeAllListeners(); 88 | AdMobInterstitial.removeAllListeners(); 89 | } 90 | 91 | showRewarded() { 92 | AdMobRewarded.showAd().catch(error => console.warn(error)); 93 | } 94 | 95 | showInterstitial() { 96 | AdMobInterstitial.showAd().catch(error => console.warn(error)); 97 | } 98 | 99 | render() { 100 | return ( 101 | 102 | 103 | 104 | (this._basicExample = el)} 108 | /> 109 |